[英]Netlink sockets does not add routes to routing table for IPv6
我希望能够添加一个新的IPv6地址,但到目前为止还不能。.程序运行成功,但路由表中没有任何反映。
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/types.h>
#define BUFSIZE 4095
struct route_info
{
char* dst_addr;
char* src_addr;
char* gateway;
char ifName[IF_NAMESIZE];
};
void fillRoutes(struct route_info* rinfo, const char* dst_addr, const char* src_addr, const char* gateway, const char* ifname)
{
int pton_fd;
pton_fd = inet_pton(AF_INET6, "2001::4", (struct in_addr *)&rinfo->dst_addr);
if (pton_fd <= 0)
{
perror("pton errror at dst_addr");
exit(EXIT_FAILURE);
}
pton_fd = inet_pton(AF_INET6, "2001::3", (struct in_addr *)&rinfo->gateway);
if (pton_fd <= 0)
{
perror("gateway error");
exit(EXIT_FAILURE);
}
}
int addAttr(struct nlmsghdr *nl, int maxlen, int type, void *data, int attr_len )
{
struct rtattr *rta;
int len = RTA_LENGTH(attr_len);
if(NLMSG_ALIGN(nl->nlmsg_len) + len > maxlen)
{
perror("inside attr()");
exit(EXIT_FAILURE);
}
nl->nlmsg_len = NLMSG_ALIGN(nl->nlmsg_len) + len;
rta = (struct rtattr *)((char *)nl + NLMSG_ALIGN(nl->nlmsg_len));
rta->rta_type = type;
rta->rta_len = len;
memcpy(RTA_DATA(rta), data, attr_len);
//nl->nlmsg_len = NLMSG_ALIGN(nl->nlmsg_len) + len;
fprintf(stderr, "attr len=%d\n",nl->nlmsg_len);
return 0;
}
int main (int argc, char **argv)
{
int bytes_sent;
int msg_seq =1;
int rtnetlink_socket = -1;
struct sockaddr_nl addr;
struct rtmsg *raddr;
struct nlmsghdr *nl;
struct iovec iov;
struct msghdr msg;
char dst_addr[30];
char src_addr[30];
char gateway[30];
char ifname[30];
char msgbuf[BUFSIZE];
struct route_info rinfo;
memset(&addr, 0, sizeof(addr));
memset(msgbuf, 0, BUFSIZE);
if ((rtnetlink_socket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
{
perror("socket");
exit(EXIT_FAILURE);
}
nl = (struct nlmsghdr *)msgbuf;
raddr = (struct rtmsg*)NLMSG_DATA(nl);
nl->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
nl->nlmsg_type = RTM_NEWROUTE;
nl->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
nl->nlmsg_seq = msg_seq++;
nl->nlmsg_pid = getpid();
//fill entries for routing table
raddr->rtm_family = AF_INET6;
raddr->rtm_dst_len = 128;
raddr->rtm_src_len = 0;
raddr->rtm_table = RT_TABLE_MAIN;
raddr->rtm_protocol = RTPROT_STATIC;
raddr->rtm_scope = RT_SCOPE_UNIVERSE;
raddr->rtm_type = RTN_UNICAST;
raddr->rtm_flags = RTM_F_NOTIFY;
raddr->rtm_tos = 0;
fillRoutes(&rinfo, dst_addr, src_addr, gateway, ifname);
addAttr(nl, BUFSIZE, RTA_DST, &rinfo.dst_addr, 16);
addAttr(nl, BUFSIZE, RTA_GATEWAY, &rinfo.gateway, 16);
if((bytes_sent = send(rtnetlink_socket, nl, nl->nlmsg_len, 0)) < 0)
{
perror("failed to write to socket");
exit(EXIT_FAILURE);
}
printf("No of bytes sent :%d\n", bytes_sent);
return 0;
}
这给我的属性值在RTA_DST时为48,在RTA_GATEWAY时为68。 我在哪里弄错了。 我似乎没有找到错误。 任何帮助表示赞赏!
您正在通过在nlmsghdr中设置错误的PID将NEWROUTE请求发送到您自己的进程。
nl-> nlmsg_pid = getpid(); / *这是您自己的进程ID * /
您需要使用PID 0 将其发送到kernel ,因此将其替换为
nl-> nlmsg_pid = 0;
将其发送到内核,然后内核才能将其合并到路由表中。
还有一点,对于通过netlink套接字发送数据/控制信息, sendmsg()
是首选的处理方式。 我不确定send()
在这里如何工作,因为它打算在连接状态下工作。 请参见手册页 。 声明send()
仅针对本地错误返回-1
,并且不会检测到远程错误,这稍后可能是另一个问题。
我已经搬家了
nl->nlmsg_len = NLMSG_ALIGN(nl->nlmsg_len) + len;
后
rta = (struct rtattr *) ((char *) nl + NLMSG_ALIGN(nl->nlmsg_len));
这有所帮助(实际上,它已经在原始代码中被注释了)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.