编程技术分享

分享编程知识,探讨技术创新

0%

简介:X86架构PC电脑主板

很高兴能和你一起探讨如何基于X86架构的PC电脑主板构建一个可靠、高效、可扩展的嵌入式系统平台,并详细阐述最适合的代码设计架构,以及提供具体的C代码实现。
关注微信公众号,提前获取相关推文

项目背景与需求分析

首先,我们需要明确这个“嵌入式系统”在X86架构PC电脑主板上的具体应用场景。虽然X86架构通常用于通用计算,但它同样可以作为高性能嵌入式系统的基础平台,尤其在需要强大处理能力、丰富外设接口和较高兼容性的场景下。

假设我们的项目目标是构建一个高性能网络安全设备,例如一个企业级的防火墙或入侵检测系统 (IDS)。这个设备需要具备以下核心功能和特性:

  1. 高速网络数据包处理: 能够实时捕获、解析和处理高速网络链路上的数据包,满足千兆甚至万兆网络环境的需求。
  2. 复杂的安全策略执行: 支持丰富的防火墙规则、访问控制列表 (ACL)、深度包检测 (DPI)、入侵检测/防御 (IDS/IPS) 等安全策略。
  3. 实时监控与告警: 能够实时监控网络流量和系统状态,及时发出安全告警。
  4. 灵活的配置管理: 提供友好的配置界面,支持远程管理和自动化配置。
  5. 高可靠性与稳定性: 系统需要长时间稳定运行,具备一定的容错能力。
  6. 可扩展性: 系统架构应具备良好的可扩展性,方便后续功能升级和性能提升。

嵌入式系统开发流程

根据嵌入式系统开发的通用流程,我们将按照以下步骤进行:

  1. 需求分析 (Requirements Analysis): 明确系统功能、性能、可靠性、安全性等方面的需求,形成详细的需求文档。
  2. 系统设计 (System Design): 根据需求文档,进行硬件选型、软件架构设计、接口定义、模块划分等,制定详细的设计方案。
  3. 系统实现 (System Implementation): 根据设计方案,进行硬件搭建、驱动开发、应用软件编写、系统集成等,完成系统的初步实现。
  4. 测试验证 (Testing and Validation): 对系统进行功能测试、性能测试、可靠性测试、安全测试等,验证系统是否满足需求,并进行问题修复和优化。
  5. 部署与维护 (Deployment and Maintenance): 将系统部署到实际应用环境中,进行长期运行和监控,并进行日常维护、故障排除、版本升级等。

代码设计架构:分层架构与模块化设计

为了构建一个可靠、高效、可扩展的嵌入式系统平台,我们采用分层架构模块化设计的思想。这种架构将系统划分为多个独立的层次和模块,每个层次和模块负责特定的功能,层次之间通过清晰定义的接口进行交互。

1. 硬件抽象层 (HAL - Hardware Abstraction Layer)

  • 目的: 隔离上层软件与底层硬件的直接耦合,提供统一的硬件访问接口,增强系统的硬件可移植性。
  • 模块:
    • CPU 初始化: 负责CPU的初始化配置,包括时钟配置、Cache配置、内存初始化等。
    • 中断控制器驱动: 管理中断的注册、使能、禁用和处理。
    • 定时器驱动: 提供硬件定时器的访问接口,用于时间管理和延时操作。
    • 内存管理驱动: 管理物理内存的分配和释放,可能包括DMA控制器的驱动。
    • 外设接口驱动: 提供各种外设接口的驱动,例如:
      • 网卡驱动 (Network Interface Card - NIC Driver): 负责网卡的初始化、数据包的发送和接收。
      • 串口驱动 (Serial Port Driver): 负责串口的初始化和数据传输。
      • USB 驱动 (USB Driver): 负责USB控制器的初始化和设备通信。
      • 存储设备驱动 (Storage Device Driver): 例如 SATA 或 NVMe 硬盘驱动。
      • 显示设备驱动 (Display Device Driver): 例如 VGA 或 HDMI 驱动(如果需要本地显示)。
      • 其他传感器或执行器驱动: 根据具体应用场景可能需要的其他硬件驱动。

2. 板级支持包 (BSP - Board Support Package)

  • 目的: 在HAL层之上,提供更高级别的硬件相关服务,为操作系统和应用层提供硬件平台的基础支持。
  • 模块:
    • 启动引导 (Bootloader): 负责系统启动时的初始化工作,加载操作系统内核。
    • 操作系统移植层 (OSAL - Operating System Abstraction Layer): 如果使用操作系统,BSP需要提供OSAL,封装操作系统相关的API,例如线程管理、同步机制、内存管理等,方便上层应用在不同操作系统之间移植。
    • 板级初始化 (Board Initialization): 进行板级特定的初始化配置,例如电源管理、温度监控等。
    • 设备树配置 (Device Tree Configuration): 如果使用Linux等支持设备树的操作系统,BSP需要提供设备树文件,描述硬件资源和配置信息。
    • 标准库和工具函数: 提供常用的数据结构、算法、字符串处理、日志打印等工具函数库。

3. 操作系统层 (OS Layer)

  • 目的: 提供系统的核心服务,例如进程/线程管理、内存管理、文件系统、网络协议栈、设备驱动框架等,简化应用软件的开发。

  • 选择: 对于X86架构的PC主板,我们可以选择多种操作系统,例如:

    • Linux: 开源、稳定、功能强大、驱动丰富,是嵌入式系统中最常用的操作系统之一,特别适合高性能和复杂的应用。
    • FreeBSD: 类似于Linux,也是开源的类Unix操作系统,以稳定性和安全性著称。
    • Windows Embedded: 微软的嵌入式操作系统,与Windows生态系统兼容性好,开发工具成熟。
    • RTOS (Real-Time Operating System): 例如 FreeRTOS, RT-Thread, Zephyr (虽然 Zephyr 更常用于微控制器,但也可以在X86上运行), 如果对实时性要求非常高,可以选择RTOS。

    在本例中,我们选择使用 Linux 作为操作系统,因为它在网络安全领域应用广泛,拥有强大的网络协议栈和丰富的安全工具。

  • 模块:

    • 内核 (Kernel): 操作系统的核心,负责进程/线程管理、内存管理、设备驱动管理、文件系统、网络协议栈等。
    • 系统库 (System Libraries): 例如 glibc, 提供标准的C库函数和系统调用接口。
    • Shell 和工具 (Shell and Utilities): 例如 Bash, coreutils, 提供命令行界面和常用工具。
    • 设备驱动框架 (Device Driver Framework): Linux内核提供的设备驱动框架,方便开发和管理设备驱动程序。
    • 网络协议栈 (Network Stack): Linux内核提供的TCP/IP协议栈,支持各种网络协议。
    • 文件系统 (File System): 例如 ext4, XFS, 提供文件存储和管理功能。

4. 中间件层 (Middleware Layer)

  • 目的: 在操作系统之上,提供更高级别的通用服务和组件,简化应用软件的开发,提高代码复用率。
  • 模块 (针对网络安全设备):
    • 网络协议处理库: 例如 libpcap (数据包捕获), DPDK (Data Plane Development Kit - 高性能数据包处理), libnet (网络数据包构造和发送), 用于高效地处理网络数据包。
    • 安全协议库: 例如 OpenSSL (SSL/TLS, 加密算法), 用于实现安全通信和数据加密。
    • 规则引擎: 用于加载和执行安全策略规则,例如 Snort 或 Suricata 的规则引擎。
    • 日志管理模块: 负责收集、存储和分析系统日志和安全事件日志。
    • 配置管理模块: 负责加载和管理系统配置信息,例如使用 YAML 或 JSON 格式的配置文件。
    • 数据库 (可选): 例如 SQLite, MySQL, PostgreSQL, 用于存储配置数据、日志数据或安全事件数据。
    • 消息队列 (可选): 例如 Redis, RabbitMQ, 用于异步任务处理和模块间通信。
    • Web 服务器 (可选): 例如 Nginx, Apache, 用于提供Web管理界面。

5. 应用层 (Application Layer)

  • 目的: 实现系统的具体业务逻辑,即网络安全设备的核心功能。
  • 模块 (针对网络安全设备):
    • 数据包捕获模块: 使用 libpcap 或 DPDK 等库捕获网络接口上的数据包。
    • 数据包解析模块: 解析数据包的协议头部,例如 Ethernet, IP, TCP, UDP, HTTP 等。
    • 安全策略执行模块: 根据配置的安全策略规则,对数据包进行过滤、检测和处理,例如防火墙规则匹配、入侵检测、深度包检测等。
    • 流量监控模块: 实时监控网络流量,统计各种指标,例如带宽利用率、连接数、协议分布等。
    • 告警模块: 当检测到安全事件或异常情况时,发出告警通知,例如邮件、短信、Syslog 等。
    • 配置管理界面: 提供命令行界面 (CLI) 或 Web 界面 (GUI) 用于配置系统参数、安全策略、查看系统状态等。
    • 系统管理模块: 负责系统启动、停止、重启、升级、备份、恢复等管理功能。

C 代码实现 (示例代码,共计超过3000行)

以下代码示例仅为演示分层架构和模块化设计的思路,并不能构成一个完整的网络安全设备系统。为了满足3000行代码的要求,示例代码会相对详细,并包含一些常用的功能模块。

1. 硬件抽象层 (HAL)

hal_cpu.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef HAL_CPU_H
#define HAL_CPU_H

#include <stdint.h>

// 初始化 CPU 时钟
void hal_cpu_init_clock(void);

// 获取 CPU 时钟频率 (MHz)
uint32_t hal_cpu_get_clock_frequency_MHz(void);

// 延时函数 (微秒级)
void hal_delay_us(uint32_t us);

// 延时函数 (毫秒级)
void hal_delay_ms(uint32_t ms);

#endif // HAL_CPU_H

hal_cpu.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "hal_cpu.h"
#include <time.h> // For nanosleep

// 假设时钟频率固定为 3.0 GHz (3000 MHz) - 实际情况需要从硬件读取或配置
#define CPU_CLOCK_FREQUENCY_MHZ 3000

void hal_cpu_init_clock(void) {
// 在 X86 架构上,时钟初始化通常由 BIOS/UEFI 完成,操作系统启动后可以进一步配置
// 这里为了示例,可以留空或添加一些简单的初始化代码 (例如读取 CPUID)
// ...
// For demonstration purposes, we can just print a message
printf("HAL: CPU clock initialized to %u MHz\n", CPU_CLOCK_FREQUENCY_MHZ);
}

uint32_t hal_cpu_get_clock_frequency_MHz(void) {
return CPU_CLOCK_FREQUENCY_MHZ;
}

void hal_delay_us(uint32_t us) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = us * 1000; // Convert microseconds to nanoseconds
nanosleep(&ts, NULL);
}

void hal_delay_ms(uint32_t ms) {
hal_delay_us(ms * 1000); // Convert milliseconds to microseconds
}

hal_interrupt.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef HAL_INTERRUPT_H
#define HAL_INTERRUPT_H

#include <stdint.h>

// 中断处理函数类型定义
typedef void (*hal_interrupt_handler_t)(void);

// 注册中断处理函数
void hal_interrupt_register_handler(uint32_t interrupt_number, hal_interrupt_handler_t handler);

// 使能中断
void hal_interrupt_enable(uint32_t interrupt_number);

// 禁用中断
void hal_interrupt_disable(uint32_t interrupt_number);

// 触发软件中断 (如果硬件支持)
void hal_interrupt_trigger_software(uint32_t interrupt_number);

#endif // HAL_INTERRUPT_H

hal_interrupt.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "hal_interrupt.h"
#include <stdio.h> // For printf (for demonstration)

#define MAX_INTERRUPT_HANDLERS 256 // 假设最多支持 256 个中断

static hal_interrupt_handler_t interrupt_handlers[MAX_INTERRUPT_HANDLERS];

void hal_interrupt_register_handler(uint32_t interrupt_number, hal_interrupt_handler_t handler) {
if (interrupt_number < MAX_INTERRUPT_HANDLERS) {
interrupt_handlers[interrupt_number] = handler;
printf("HAL: Registered interrupt handler for interrupt %u\n", interrupt_number);
} else {
printf("HAL: Error: Interrupt number %u out of range\n", interrupt_number);
}
}

void hal_interrupt_enable(uint32_t interrupt_number) {
if (interrupt_number < MAX_INTERRUPT_HANDLERS) {
// 在 X86 架构上,中断使能通常通过设置中断控制器的寄存器来实现
// 这里为了示例,可以留空或添加一些简单的代码 (例如打印消息)
printf("HAL: Enabled interrupt %u\n", interrupt_number);
} else {
printf("HAL: Error: Interrupt number %u out of range\n", interrupt_number);
}
}

void hal_interrupt_disable(uint32_t interrupt_number) {
if (interrupt_number < MAX_INTERRUPT_HANDLERS) {
// 在 X86 架构上,中断禁用通常通过设置中断控制器的寄存器来实现
// 这里为了示例,可以留空或添加一些简单的代码 (例如打印消息)
printf("HAL: Disabled interrupt %u\n", interrupt_number);
} else {
printf("HAL: Error: Interrupt number %u out of range\n", interrupt_number);
}
}

void hal_interrupt_trigger_software(uint32_t interrupt_number) {
if (interrupt_number < MAX_INTERRUPT_HANDLERS) {
// 触发软件中断的实现取决于具体的硬件和操作系统
// 在 Linux 上,可以使用 kill -s SIGUSR1 <pid> 等方式发送信号模拟软件中断
printf("HAL: Triggered software interrupt %u (Simulated)\n", interrupt_number);
if (interrupt_handlers[interrupt_number] != NULL) {
interrupt_handlers[interrupt_number](); // 调用注册的中断处理函数
}
} else {
printf("HAL: Error: Interrupt number %u out of range\n", interrupt_number);
}
}

// 示例中断处理函数 (用于测试)
void hal_example_interrupt_handler(void) {
printf("HAL: Example interrupt handler called!\n");
}

hal_timer.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef HAL_TIMER_H
#define HAL_TIMER_H

#include <stdint.h>

// 初始化定时器
void hal_timer_init(uint32_t timer_id, uint32_t frequency_hz);

// 启动定时器
void hal_timer_start(uint32_t timer_id);

// 停止定时器
void hal_timer_stop(uint32_t timer_id);

// 获取当前定时器计数值
uint32_t hal_timer_get_count(uint32_t timer_id);

// 设置定时器回调函数
void hal_timer_set_callback(uint32_t timer_id, void (*callback)(void));

#endif // HAL_TIMER_H

hal_timer.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "hal_timer.h"
#include <stdio.h> // For printf (for demonstration)
#include <pthread.h> // For threads (for simulated timer)
#include <unistd.h> // For usleep (for simulated timer)

#define MAX_TIMERS 4 // 假设最多支持 4 个定时器

typedef struct {
uint32_t frequency_hz;
void (*callback)(void);
pthread_t thread;
int running;
} hal_timer_context_t;

static hal_timer_context_t timers[MAX_TIMERS];

// 模拟定时器线程函数
void* hal_timer_thread_func(void* arg) {
int timer_id = *((int*)arg);
hal_timer_context_t* timer = &timers[timer_id];
uint32_t period_us = 1000000 / timer->frequency_hz; // 计算定时周期 (微秒)

while (timer->running) {
usleep(period_us); // 模拟定时器周期
if (timer->callback != NULL) {
timer->callback(); // 调用回调函数
}
}
return NULL;
}

void hal_timer_init(uint32_t timer_id, uint32_t frequency_hz) {
if (timer_id < MAX_TIMERS) {
timers[timer_id].frequency_hz = frequency_hz;
timers[timer_id].callback = NULL;
timers[timer_id].running = 0;
printf("HAL: Timer %u initialized with frequency %u Hz\n", timer_id, frequency_hz);
} else {
printf("HAL: Error: Timer ID %u out of range\n", timer_id);
}
}

void hal_timer_start(uint32_t timer_id) {
if (timer_id < MAX_TIMERS && !timers[timer_id].running) {
timers[timer_id].running = 1;
int* timer_id_ptr = malloc(sizeof(int)); // 动态分配内存传递 timer_id
*timer_id_ptr = timer_id;
if (pthread_create(&timers[timer_id].thread, NULL, hal_timer_thread_func, timer_id_ptr) != 0) {
perror("HAL: Error creating timer thread");
timers[timer_id].running = 0;
free(timer_id_ptr); // 释放分配的内存
} else {
printf("HAL: Timer %u started\n", timer_id);
}
} else {
printf("HAL: Error: Timer %u already running or invalid ID\n", timer_id);
}
}

void hal_timer_stop(uint32_t timer_id) {
if (timer_id < MAX_TIMERS && timers[timer_id].running) {
timers[timer_id].running = 0;
pthread_join(timers[timer_id].thread, NULL); // 等待线程结束
printf("HAL: Timer %u stopped\n", timer_id);
} else {
printf("HAL: Error: Timer %u not running or invalid ID\n", timer_id);
}
}

uint32_t hal_timer_get_count(uint32_t timer_id) {
// 模拟定时器计数,实际硬件定时器需要读取硬件寄存器
// 这里简单返回一个递增的计数器 (仅用于演示)
static uint32_t count[MAX_TIMERS] = {0};
if (timer_id < MAX_TIMERS) {
return count[timer_id]++;
} else {
printf("HAL: Error: Timer ID %u out of range\n", timer_id);
return 0;
}
}

void hal_timer_set_callback(uint32_t timer_id, void (*callback)(void)) {
if (timer_id < MAX_TIMERS) {
timers[timer_id].callback = callback;
printf("HAL: Timer %u callback set\n", timer_id);
} else {
printf("HAL: Error: Timer ID %u out of range\n", timer_id);
}
}

// 示例定时器回调函数 (用于测试)
void hal_example_timer_callback(void) {
printf("HAL: Timer callback triggered!\n");
}

hal_memory.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef HAL_MEMORY_H
#define HAL_MEMORY_H

#include <stdint.h>
#include <stddef.h> // For size_t

// 内存分配
void* hal_malloc(size_t size);

// 内存释放
void hal_free(void* ptr);

// 内存拷贝
void* hal_memcpy(void* dest, const void* src, size_t n);

// 内存设置
void* hal_memset(void* s, int c, size_t n);

#endif // HAL_MEMORY_H

hal_memory.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "hal_memory.h"
#include <stdlib.h> // For malloc, free, memcpy, memset

void* hal_malloc(size_t size) {
return malloc(size);
}

void hal_free(void* ptr) {
free(ptr);
}

void* hal_memcpy(void* dest, const void* src, size_t n) {
return memcpy(dest, src, n);
}

void* hal_memset(void* s, int c, size_t n) {
return memset(s, c, n);
}

2. 板级支持包 (BSP)

bsp.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef BSP_H
#define BSP_H

#include <stdint.h>

// 初始化 BSP
void bsp_init(void);

// 获取板卡型号
const char* bsp_get_board_model(void);

// 获取 MAC 地址 (假设板卡有网卡)
uint8_t* bsp_get_mac_address(void);

// 系统重启
void bsp_reset(void);

#endif // BSP_H

bsp.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "bsp.h"
#include <stdio.h> // For printf
#include <string.h> // For strcpy

#include "hal_cpu.h" // 引用 HAL 层头文件
#include "hal_interrupt.h"
#include "hal_timer.h"
#include "hal_memory.h"

void bsp_init(void) {
printf("BSP: Initializing Board Support Package...\n");

// 初始化 HAL 层
hal_cpu_init_clock();
printf("BSP: HAL CPU initialized\n");

// 初始化中断控制器 (示例 - 注册一个示例中断处理函数)
hal_interrupt_register_handler(10, hal_example_interrupt_handler); // 假设中断号 10
hal_interrupt_enable(10);
printf("BSP: HAL Interrupt controller initialized\n");

// 初始化定时器 (示例 - 初始化定时器 0,频率 10Hz,并设置回调函数)
hal_timer_init(0, 10);
hal_timer_set_callback(0, hal_example_timer_callback);
hal_timer_start(0);
printf("BSP: HAL Timer initialized\n");

// 其他板级初始化 (例如网卡、串口、内存等) ...
printf("BSP: Board initialization completed.\n");
}

const char* bsp_get_board_model(void) {
// 实际情况需要从硬件读取或配置文件获取板卡型号
static char model_name[] = "X86_PC_Motherboard_V1.0";
return model_name;
}

uint8_t* bsp_get_mac_address(void) {
// 实际情况需要从网卡硬件读取 MAC 地址
static uint8_t mac_address[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; // 示例 MAC 地址
return mac_address;
}

void bsp_reset(void) {
printf("BSP: System Resetting...\n");
// 执行系统重启操作 (具体实现取决于硬件和操作系统)
// 在 Linux 上可以使用 system("reboot") 或 reboot() 系统调用
system("reboot");
}

3. 操作系统层 (OS Layer) - 示例代码基于 Linux

这部分代码主要是在 Linux 用户空间编写的应用层代码,Linux 内核已经提供了操作系统层的核心功能,例如进程管理、内存管理、设备驱动框架、网络协议栈等。 我们只需要使用 Linux 提供的系统调用和库函数即可。

4. 中间件层 (Middleware Layer) - 示例代码

middleware_network.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef MIDDLEWARE_NETWORK_H
#define MIDDLEWARE_NETWORK_H

#include <stdint.h>
#include <stdbool.h>

// 初始化网络接口
bool middleware_network_init_interface(const char* interface_name);

// 启动网络接口
bool middleware_network_start_interface(const char* interface_name);

// 停止网络接口
bool middleware_network_stop_interface(const char* interface_name);

// 发送 IP 数据包
bool middleware_network_send_ip_packet(const uint8_t* dest_mac, uint32_t dest_ip, uint16_t protocol, const uint8_t* payload, uint32_t payload_len);

// 注册数据包接收回调函数
void middleware_network_register_packet_callback(void (*callback)(const uint8_t* packet, uint32_t packet_len));

#endif // MIDDLEWARE_NETWORK_H

middleware_network.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#include "middleware_network.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ether.h>
#include <arpa/inet.h>
#include <errno.h>

#include "hal_memory.h" // 引用 HAL 内存管理

#define ETHER_TYPE_IP 0x0800

static void (*packet_callback)(const uint8_t* packet, uint32_t packet_len) = NULL;
static int raw_socket_fd = -1;
static char current_interface_name[IF_NAMESIZE] = "";

// 数据包接收线程函数
void* middleware_network_receive_thread(void* arg) {
uint8_t buffer[2048]; // 数据包缓冲区
ssize_t recv_len;

while (1) {
recv_len = recvfrom(raw_socket_fd, buffer, sizeof(buffer), 0, NULL, NULL);
if (recv_len < 0) {
perror("Middleware Network: Error receiving packet");
continue;
}

if (packet_callback != NULL) {
packet_callback(buffer, recv_len); // 调用数据包接收回调函数
}
}
return NULL; // Never reaches here in this example
}

bool middleware_network_init_interface(const char* interface_name) {
if (raw_socket_fd != -1) {
close(raw_socket_fd); // 关闭之前的 socket
raw_socket_fd = -1;
}

raw_socket_fd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE_IP)); // 创建 RAW socket
if (raw_socket_fd < 0) {
perror("Middleware Network: Error creating raw socket");
return false;
}

struct ifreq ifr;
strncpy(ifr.ifr_name, interface_name, IF_NAMESIZE - 1);
ifr.ifr_name[IF_NAMESIZE - 1] = '\0';

if (ioctl(raw_socket_fd, SIOCGIFINDEX, &ifr) < 0) {
perror("Middleware Network: ioctl SIOCGIFINDEX failed");
close(raw_socket_fd);
raw_socket_fd = -1;
return false;
}

struct sockaddr_ll sll;
memset(&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(ETHER_TYPE_IP);

if (bind(raw_socket_fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) {
perror("Middleware Network: bind failed");
close(raw_socket_fd);
raw_socket_fd = -1;
return false;
}
strncpy(current_interface_name, interface_name, IF_NAMESIZE - 1);
current_interface_name[IF_NAMESIZE - 1] = '\0';

pthread_t recv_thread;
if (pthread_create(&recv_thread, NULL, middleware_network_receive_thread, NULL) != 0) {
perror("Middleware Network: Error creating receive thread");
close(raw_socket_fd);
raw_socket_fd = -1;
return false;
}

printf("Middleware Network: Interface '%s' initialized.\n", interface_name);
return true;
}

bool middleware_network_start_interface(const char* interface_name) {
if (raw_socket_fd == -1 || strcmp(interface_name, current_interface_name) != 0) {
if (!middleware_network_init_interface(interface_name)) {
return false; // 初始化失败
}
}

struct ifreq ifr;
strncpy(ifr.ifr_name, interface_name, IF_NAMESIZE - 1);
ifr.ifr_name[IF_NAMESIZE - 1] = '\0';

if (ioctl(raw_socket_fd, SIOCGIFFLAGS, &ifr) < 0) {
perror("Middleware Network: ioctl SIOCGIFFLAGS get failed");
return false;
}

ifr.ifr_flags |= IFF_UP | IFF_RUNNING;

if (ioctl(raw_socket_fd, SIOCSIFFLAGS, &ifr) < 0) {
perror("Middleware Network: ioctl SIOCSIFFLAGS set failed");
return false;
}

printf("Middleware Network: Interface '%s' started.\n", interface_name);
return true;
}

bool middleware_network_stop_interface(const char* interface_name) {
if (raw_socket_fd == -1 || strcmp(interface_name, current_interface_name) != 0) {
return true; // 接口未初始化或已切换,无需停止 (可以考虑返回错误,这里简化处理)
}

struct ifreq ifr;
strncpy(ifr.ifr_name, interface_name, IF_NAMESIZE - 1);
ifr.ifr_name[IF_NAMESIZE - 1] = '\0';

if (ioctl(raw_socket_fd, SIOCGIFFLAGS, &ifr) < 0) {
perror("Middleware Network: ioctl SIOCGIFFLAGS get failed");
return false;
}

ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);

if (ioctl(raw_socket_fd, SIOCSIFFLAGS, &ifr) < 0) {
perror("Middleware Network: ioctl SIOCSIFFLAGS set failed");
return false;
}

printf("Middleware Network: Interface '%s' stopped.\n", interface_name);
return true;
}

bool middleware_network_send_ip_packet(const uint8_t* dest_mac, uint32_t dest_ip, uint16_t protocol, const uint8_t* payload, uint32_t payload_len) {
if (raw_socket_fd == -1 || current_interface_name[0] == '\0') {
fprintf(stderr, "Middleware Network: Interface not initialized or started.\n");
return false;
}

// 构建 Ethernet 头部
struct ether_header *eth_hdr = (struct ether_header *)hal_malloc(sizeof(struct ether_header) + payload_len + sizeof(struct iphdr));
if (eth_hdr == NULL) {
perror("Middleware Network: malloc ether_header failed");
return false;
}
memset(eth_hdr, 0, sizeof(struct ether_header));

// 目标 MAC 地址
memcpy(eth_hdr->ether_dhost, dest_mac, ETH_ALEN);

// 源 MAC 地址 (从接口获取)
struct ifreq ifr;
strncpy(ifr.ifr_name, current_interface_name, IF_NAMESIZE - 1);
ifr.ifr_name[IF_NAMESIZE - 1] = '\0';
if (ioctl(raw_socket_fd, SIOCGIFHWADDR, &ifr) < 0) {
perror("Middleware Network: ioctl SIOCGIFHWADDR failed");
hal_free(eth_hdr);
return false;
}
memcpy(eth_hdr->ether_shost, ifr.ifr_hwaddr.sa_data, ETH_ALEN);

// 以太网协议类型
eth_hdr->ether_type = htons(ETHER_TYPE_IP);

// 构建 IP 头部
struct iphdr *ip_hdr = (struct iphdr *)((uint8_t*)eth_hdr + sizeof(struct ether_header));
ip_hdr->version = 4;
ip_hdr->ihl = 5; // IP Header Length = 5 * 4 bytes = 20 bytes
ip_hdr->tos = 0;
ip_hdr->tot_len = htons(sizeof(struct iphdr) + payload_len);
ip_hdr->id = htons(rand()); // 随机 ID
ip_hdr->frag_off = 0;
ip_hdr->ttl = 64;
ip_hdr->protocol = protocol; // 例如 IPPROTO_TCP, IPPROTO_UDP
ip_hdr->check = 0; // 校验和稍后计算
ip_hdr->saddr = INADDR_ANY; // 源 IP 地址 (让内核自动填充)
ip_hdr->daddr = dest_ip;

// 计算 IP 校验和
ip_hdr->check = 0; // 先清零
uint16_t checksum = 0;
uint16_t *ip_header_ptr = (uint16_t *)ip_hdr;
for (int i = 0; i < ip_hdr->ihl * 2; i++) { // 遍历 IP 头部 (以 16-bit 为单位)
checksum += *ip_header_ptr++;
}
while (checksum >> 16) { // 处理溢出
checksum = (checksum & 0xFFFF) + (checksum >> 16);
}
ip_hdr->check = ~checksum; // 取反

// 拷贝 payload 数据
memcpy((uint8_t*)ip_hdr + sizeof(struct iphdr), payload, payload_len);

// 发送数据包
struct sockaddr_ll dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sll_family = AF_PACKET;
dest_addr.sll_ifindex = ifr.ifr_ifindex;
dest_addr.sll_halen = ETH_ALEN;
memcpy(dest_addr.sll_addr, dest_mac, ETH_ALEN);

ssize_t sent_len = sendto(raw_socket_fd, eth_hdr, sizeof(struct ether_header) + sizeof(struct iphdr) + payload_len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
if (sent_len < 0) {
perror("Middleware Network: sendto failed");
hal_free(eth_hdr);
return false;
}

hal_free(eth_hdr);
return true;
}

void middleware_network_register_packet_callback(void (*callback)(const uint8_t* packet, uint32_t packet_len)) {
packet_callback = callback;
printf("Middleware Network: Packet callback registered.\n");
}

// 示例数据包接收回调函数
void middleware_example_packet_callback(const uint8_t* packet, uint32_t packet_len) {
printf("Middleware Network: Received packet, length: %u bytes\n", packet_len);
// 在这里可以进行数据包解析和处理
// ...
}

middleware_security.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef MIDDLEWARE_SECURITY_H
#define MIDDLEWARE_SECURITY_H

#include <stdint.h>
#include <stdbool.h>

// 初始化安全规则引擎
bool middleware_security_init_rule_engine(const char* rule_file_path);

// 加载安全规则
bool middleware_security_load_rules(const char* rule_file_path);

// 应用安全规则到数据包
bool middleware_security_apply_rules(const uint8_t* packet, uint32_t packet_len);

#endif // MIDDLEWARE_SECURITY_H

middleware_security.c:

#include "middleware_security.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 简单的规则结构体 (示例)
typedef struct {
    char rule_description[256];
    uint32_t src_ip;
    uint32_t dest_ip;
    uint16_t src_port;
    uint16_t dest_port;
    uint8_t protocol; // 例如 TCP, UDP, ICMP
    // ... 其他规则字段
    bool action_permit; // true: 允许,false: 拒绝
} security_rule_t;

#define MAX_RULES 100 // 假设最多支持 100 条规则
static security_rule_t rules[MAX_RULES];
static uint32_t rule_count = 0;

bool middleware_security_init_rule_engine(const char* rule_file_path) {
    rule_count = 0; // 初始化规则计数
    return middleware_security_load_rules(rule_file_path); // 加载规则
}

bool middleware_security_load_rules(const char* rule_file_path) {
    FILE* rule_file = fopen(rule_file_path, "r");
    if (rule_file == NULL) {
        perror("Middleware Security: Error opening rule file");
        return false;
    }

    char line[512];
    rule_count = 0; // 重新加载规则时重置计数

    while (fgets(line, sizeof(line), rule_file) != NULL && rule_count < MAX_RULES) {
        // 简单的规则解析 (实际情况需要更完善的规则解析器)
        if (line[0] == '#' || line[0] == '\n') continue; // 忽略注释行和空行

        security_rule_t* rule = &rules[rule_count++];
        memset(rule, 0, sizeof(security_rule_t));

        // 示例规则格式 (简单空格分隔): description src_ip dest_ip src_port dest_port protocol action
    }
}

欢迎关注我的其它发布渠道