好的,这里是修改后的函数:
int add_route(vrrp_route_t *route) {
int fd = -1;
struct rtentry entry = {0};
if (route->version == 1) { // IPv4 路由表项
vrrp_route_ipv4_t *ipv4_info = &route->ipv4_info;
// 将字符串类型的地址转换为网络字节序下的二进制形式
inet_pton(AF_INET, ipv4_info->destination, &entry.rt_dst);
inet_pton(AF_INET, ipv4_info->gateway, &entry.rt_gateway);
inet_pton(AF_INET, ipv4_info->genmask, &entry.rt_genmask);
entry.rt_flags = atoi(ipv4_info->flags);
entry.rt_metric = ipv4_info->metric;
entry.rt_dev = ipv4_info->iface;
entry.rt_priority = ipv4_info->table_id;
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // 打开一个 UDP 套接字用于操作路由表
} else if (route->version == 2) { // IPv6 路由表项
vrrp_route_ipv6_t *ipv6_info = &route->ipv6_info;
memcpy(&entry.rt_dst, &(ipv6_info->destination), sizeof(struct in6_addr));
memcpy(&entry.rt_gateway, &(ipv6_info->gateway), sizeof(struct in6_addr));
entry.rt_flags = atoi(ipv6_info->flags);
entry.rt_metric = ipv6_info->metric;
entry.rt_dev = ipv6_info->iface;
entry.rt_priority=ipv6_info ->table_id;
entry.rt_prefixlen=ipv6_info ->prefixlen;
fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
}
if (fd < 0) {
perror("socket");
return -1;
}
int ret = ioctl(fd, SIOCADDRT, &entry); // 添加路由表项
close(fd);
if (ret < 0) {
perror("ioctl");
return -1;
}
return 0;
}
修改说明:
- 根据输入的
vrrp_route_t
结构体判断其 IP 版本,分别处理 IPv4 和 IPv6 路由表项。 - 对于 IPv4 路由表项,使用
inet_pton
函数将字符串类型的地址转换为网络字节序下的二进制形式,并填充到结构体中。 - 对于 IPv6 路由表项,直接拷贝结构体成员。
- 在打开套接字时根据 IP 版本选择相应的协议族(IPv4 或 IPv6)和套接字类型(UDP),这样才能正确地操作路由表。