macOS内核路由表编程全解析
macOS 内核路由表操作:直接 API 编程指南
路由表操作的核心 API
macOS 提供了 BSD 套接字层和系统配置框架来操作内核路由表。关键 API 包括 route.h 头文件中的函数和 SystemConfiguration.framework 中的高级封装。
路由表操作的核心函数:
route():BSD 层原始路由操作函数getrtable():获取当前路由表 IDsetrtable():设置当前路由表 IDsysctl():通过 MIB 访问路由信息
基础路由操作
路由表查询使用 sysctl 接口:
int mib[6];
size_t needed;
char *buf, *next;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = 0;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
perror("sysctl estimate");
exit(1);
}
buf = malloc(needed);
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
perror("sysctl get");
free(buf);
exit(1);
}
路由添加使用 route() 函数:
struct rt_msghdr *rtm;
struct sockaddr_in dst, mask, gw;
char buf[1024];
memset(&dst, 0, sizeof(dst));
dst.sin_len = sizeof(dst);
dst.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.0", &dst.sin_addr);
memset(&mask, 0, sizeof(mask));
mask.sin_len = sizeof(mask);
mask.sin_family = AF_INET;
inet_pton(AF_INET, "255.255.255.0", &mask.sin_addr);
memset(&gw, 0, sizeof(gw));
gw.sin_len = sizeof(gw);
gw.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.1", &gw.sin_addr);
rtm = (struct rt_msghdr *)buf;
rtm->rtm_msglen = sizeof(*rtm) + 3 * sizeof(dst);
rtm->rtm_version = RTM_VERSION;
rtm->rtm_type = RTM_ADD;
rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
rtm->rtm_pid = getpid();
rtm->rtm_seq = 1;
char *cp = buf + sizeof(*rtm);
memcpy(cp, &dst, sizeof(dst)); cp += sizeof(dst);
memcpy(cp, &gw, sizeof(gw)); cp += sizeof(gw);
memcpy(cp, &mask, sizeof(mask));
if (write(routing_socket, buf, rtm->rtm_msglen) < 0) {
perror("route add failed");
}
多路由表支持
macOS 支持多路由表(VRF):
int tableid = 100;
if (setrtable(tableid) < 0) {
perror("setrtable");
}
int current_table = getrtable();
printf("Current routing table ID: %d\n", current_table);
高级 SystemConfiguration API
使用 SystemConfiguration 框架更安全的方式:
#import <SystemConfiguration/SystemConfiguration.h>
BOOL addRoute(NSString *dest, NSString *mask, NSString *gateway) {
SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("routeadd"), NULL, NULL);
NSDictionary *dict = @{
(__bridge NSString *)kSCPropNetDestinationAddress : dest,
(__bridge NSString *)kSCPropNetSubnetMask : mask,
(__bridge NSString *)kSCPropNetGatewayAddress : gateway
};
Boolean success = SCDynamicStoreAddValue(store, CFSTR("State:/Network/Global/IPv4"), (__bridge CFDictionaryRef)dict);
CFRelease(store);
return success;
}
路由监控
实时监控路由表变化:
int routing_socket = socket(PF_ROUTE, SOCK_RAW, 0);
char buffer[4096];
struct rt_msghdr *rtm;
while (1) {
ssize_t n = read(routing_socket, buffer, sizeof(buffer));
if (n < 0) {
perror("read routing socket");
continue;
}
rtm = (struct rt_msghdr *)buffer;
if (rtm->rtm_type == RTM_ADD) {
printf("Route added\n");
} else if (rtm->rtm_type == RTM_DELETE) {
printf("Route deleted\n");
}
}
注意事项
直接操作内核路由表需要 root 权限。所有路由修改在系统重启后不会持久化,持久化路由需要将配置写入网络配置文件。
IPv6 路由操作需要使用 sockaddr_in6 结构体。多播路由需要设置 RTF_MULTICAST 标志。路由操作可能触发系统防火墙规则,需要正确处理。
BbS.okane060.info/PoSt/1121_728199.HtM
BbS.okane061.info/PoSt/1121_165586.HtM
BbS.okane062.info/PoSt/1121_548168.HtM
BbS.okane063.info/PoSt/1121_873327.HtM
BbS.okane065.info/PoSt/1121_521601.HtM
BbS.okane066.info/PoSt/1121_746768.HtM
BbS.okane067.info/PoSt/1121_153102.HtM
BbS.okane068.info/PoSt/1121_479636.HtM
BbS.okane069.info/PoSt/1121_898216.HtM
BbS.okane070.info/PoSt/1121_303457.HtM
BbS.okane060.info/PoSt/1121_337465.HtM
BbS.okane061.info/PoSt/1121_124158.HtM
BbS.okane062.info/PoSt/1121_239608.HtM
BbS.okane063.info/PoSt/1121_161485.HtM
BbS.okane065.info/PoSt/1121_146877.HtM
BbS.okane066.info/PoSt/1121_248632.HtM
BbS.okane067.info/PoSt/1121_942261.HtM
BbS.okane068.info/PoSt/1121_533609.HtM
BbS.okane069.info/PoSt/1121_487357.HtM
BbS.okane070.info/PoSt/1121_146505.HtM
BbS.okane060.info/PoSt/1121_750461.HtM
BbS.okane061.info/PoSt/1121_183025.HtM
BbS.okane062.info/PoSt/1121_828280.HtM
BbS.okane063.info/PoSt/1121_311540.HtM
BbS.okane065.info/PoSt/1121_804210.HtM
BbS.okane066.info/PoSt/1121_466722.HtM
BbS.okane067.info/PoSt/1121_028845.HtM
BbS.okane068.info/PoSt/1121_750437.HtM
BbS.okane069.info/PoSt/1121_170199.HtM
BbS.okane070.info/PoSt/1121_780791.HtM
BbS.okane060.info/PoSt/1121_499828.HtM
BbS.okane061.info/PoSt/1121_308772.HtM
BbS.okane062.info/PoSt/1121_332539.HtM
BbS.okane063.info/PoSt/1121_359382.HtM
BbS.okane065.info/PoSt/1121_427351.HtM
BbS.okane066.info/PoSt/1121_662083.HtM
BbS.okane067.info/PoSt/1121_936273.HtM
BbS.okane068.info/PoSt/1121_565606.HtM
BbS.okane069.info/PoSt/1121_513229.HtM
BbS.okane070.info/PoSt/1121_763171.HtM
BbS.okane060.info/PoSt/1121_650874.HtM
BbS.okane061.info/PoSt/1121_165025.HtM
BbS.okane062.info/PoSt/1121_304782.HtM
BbS.okane063.info/PoSt/1121_049366.HtM
BbS.okane065.info/PoSt/1121_878489.HtM
BbS.okane066.info/PoSt/1121_977369.HtM
BbS.okane067.info/PoSt/1121_639066.HtM
BbS.okane068.info/PoSt/1121_542484.HtM
BbS.okane069.info/PoSt/1121_381816.HtM
BbS.okane070.info/PoSt/1121_392645.HtM
BbS.okane060.info/PoSt/1121_860961.HtM
BbS.okane061.info/PoSt/1121_849637.HtM
BbS.okane062.info/PoSt/1121_492626.HtM
BbS.okane063.info/PoSt/1121_986740.HtM
BbS.okane065.info/PoSt/1121_382298.HtM
BbS.okane066.info/PoSt/1121_436497.HtM
BbS.okane067.info/PoSt/1121_123039.HtM
BbS.okane068.info/PoSt/1121_087332.HtM
BbS.okane069.info/PoSt/1121_925717.HtM
BbS.okane070.info/PoSt/1121_411945.HtM
BbS.okane071.info/PoSt/1121_317193.HtM
BbS.okane072.info/PoSt/1121_392258.HtM
BbS.okane073.info/PoSt/1121_365845.HtM
BbS.okane074.info/PoSt/1121_905498.HtM
BbS.okane075.info/PoSt/1121_283234.HtM
BbS.okane076.info/PoSt/1121_583201.HtM
BbS.okane077.info/PoSt/1121_093817.HtM
BbS.okane078.info/PoSt/1121_605623.HtM
BbS.okane079.info/PoSt/1121_134209.HtM
BbS.okane080.info/PoSt/1121_991109.HtM
BbS.okane071.info/PoSt/1121_793339.HtM
BbS.okane072.info/PoSt/1121_039786.HtM
BbS.okane073.info/PoSt/1121_208287.HtM
BbS.okane074.info/PoSt/1121_882159.HtM
BbS.okane075.info/PoSt/1121_010888.HtM
BbS.okane076.info/PoSt/1121_769037.HtM
BbS.okane077.info/PoSt/1121_535256.HtM
BbS.okane078.info/PoSt/1121_165165.HtM
BbS.okane079.info/PoSt/1121_843971.HtM
BbS.okane080.info/PoSt/1121_969551.HtM

