Привет всем. Используя rtnetlink, получаю адрес шлюза. В man 7 rtnetlink есть опция в rtm_flags с названием RTM_F_NOTIFY. описание (if the route changes, notify the user via rtnetlink) (если маршрут измениться, уведомить пользователя через rtnetlink)
Но у меня не происходит уведомления, не приходит новых сообщений, что не так?
#include <stdio.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/if_link.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <strings.h>
#include <string.h>
#include <arpa/inet.h>
struct
{
struct nlmsghdr nh;
struct rtmsg rtmsg;
char buf[8192];
}req;
int main(int argc, char *argv[])
{
int rtnetlink_socket;
if((rtnetlink_socket = socket(AF_NETLINK,SOCK_DGRAM,NETLINK_ROUTE)) == -1)
{
perror("socket");
exit(-1);
}
memset(&req,0,sizeof(req));
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.nh.nlmsg_type = RTM_GETROUTE;
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
req.rtmsg.rtm_family = AF_INET;
req.rtmsg.rtm_table = 0;
req.rtmsg.rtm_type = RTN_UNICAST;
req.rtmsg.rtm_protocol = RTPROT_STATIC;
req.rtmsg.rtm_scope = RT_SCOPE_LINK;
req.rtmsg.rtm_flags = RTM_F_NOTIFY;
req.rtmsg.rtm_table = RT_TABLE_MAIN;
unsigned int intaddr = 0;
struct rtattr *rta;
rta = (struct rtattr *)(((char *) &req) + NLMSG_ALIGN(req.nh.nlmsg_len));
rta->rta_type = RTA_GATEWAY;
rta->rta_len = RTA_LENGTH(sizeof(unsigned int));
req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + RTA_LENGTH(sizeof(intaddr));
memcpy(RTA_DATA(rta), &intaddr, sizeof(intaddr));
if(send(rtnetlink_socket,&req,req.nh.nlmsg_len,0) == -1)
{
perror("send");
close(rtnetlink_socket);
exit(-1);
}
int recvlen = 0;
int counter = 8192;
char buffer[counter];
struct nlmsghdr *nl;
int replylen = 0;
int i = 0;
for(;;)
{
recvlen = recv(rtnetlink_socket,&buffer,1500,0);
printf("recvlen = %d\n",recvlen);
if(recvlen < 0)
{
printf("recvlen < 0\n");
break;
}
if(recvlen == 0)
printf("eof in netlink\n");
int nll;
struct rtmsg *rtp;
nl = (struct nlmsghdr *)&buffer[replylen];
rtp = (struct rtmsg *) NLMSG_DATA(nl);
if(rtp->rtm_table != RT_TABLE_MAIN)
{
printf("non table main %d\n",rtp->rtm_table);
continue;
}
char gws[24];
struct rtattr *rtap;
rtap = (struct rtattr *) RTM_RTA(rtp);
int rtl = 0;
rtl = RTM_PAYLOAD(nl);
for(; RTA_OK(rtap,rtl);rtap=RTA_NEXT(rtap,rtl))
{
switch(rtap->rta_type)
{
case RTA_GATEWAY:
inet_ntop(AF_INET, RTA_DATA(rtap),gws,24);
printf("%s\n",gws);
// return 0;
break;
}
}
if(nl->nlmsg_type == NLMSG_DONE)
{
printf("nlmsg done\n");
break;
}
if(nl->nlmsg_type == NLMSG_ERROR)
{
printf("error in nl\n");
exit(-1);
}
if(nl->nlmsg_type == NLMSG_NOOP)
{
printf("nothing.\n");
exit(-1);
}
if(nl->nlmsg_type == NLMSG_OVERRUN)
{
printf("data lost\n");
exit(-1);
}
if(nl->nlmsg_type == NLMSG_MIN_TYPE)
{
printf("reserved control message\n");
exit(-1);
}
replylen += recvlen;
counter -= recvlen;
}
close(rtnetlink_socket);
}