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
|
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libnetlink.h>
#define BUFF_SIZE 1024
int main(int argc, char *argv[])
{
/* All the declarations and initializations relevant to the creation of the netlink socket to communicate with routing table */
int netlink_route_socket = 0;
/* All the declarations and initializations relevant to the binding of the socket to the local protocol address */
struct sockaddr_nl src_addr;
int bind_netlink_route_socket = 0;
/* All the declarations and initializations relevant to the creation and sending of the netlink message */
int m_nSeqNumber = 1;
int send_netlink_message = 0;
struct nlmsghdr *m_nlh;
struct iovec m_iov;
struct msghdr m_msghdr;
struct sockaddr_nl nladdr;
/* All the declarations and initializations relevant to the receiving of netlink messages */
int receive_netlink_message = 0;
int flag = 0;
int nb_addr_added = 0;
char buff[BUFF_SIZE];
char buf[4096];
struct nlmsghdr *p_netlink_message_header_received;
struct iovec iov;
struct msghdr msg;
struct sockaddr_nl sa;
struct ifinfomsg *p_ifinfomsg = NULL;
struct ifaddrmsg *p_ifaddrmsg = NULL;
struct rtattr *p_rtattr = NULL;
netlink_route_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(netlink_route_socket < 0){
perror("socket");
exit(-1);
}
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pad = 0;
src_addr.nl_pid = getpid();
src_addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; //RTMGRP_LINK (network interface create/delete/up/down events) and
//RTMGRP_IPV4_IFADDR (IPv4 addresses add/delete events) multicast groups
bind_netlink_route_socket = bind(netlink_route_socket, (struct sockaddr *)&src_addr, sizeof(src_addr));
if(bind_netlink_route_socket < 0){
perror("bind");
close(netlink_route_socket);
exit(-1);
}
m_msghdr.msg_name = (void *)&nladdr;
m_msghdr.msg_namelen = sizeof(nladdr);
m_msghdr.msg_iov = &m_iov;
m_msghdr.msg_iovlen = 1;
m_msghdr.msg_control = NULL;
m_msghdr.msg_controllen = 0;
m_msghdr.msg_flags = 0;
m_nlh = (struct nlmsghdr *)malloc NLMSG_SPACE(BUFF_SIZE);
m_nlh->nlmsg_pid = 0;
m_nlh->nlmsg_seq = m_nSeqNumber++;
m_nlh->nlmsg_len = NLMSG_SPACE(BUFF_SIZE);
m_nlh->nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK;
//m_nlh->nlmsg_type = RTM_GETLINK;
m_iov.iov_base = (void *) m_nlh;
m_iov.iov_len = m_nlh->nlmsg_len;
memset (&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
send_netlink_message = sendmsg(netlink_route_socket, &m_msghdr, 0);
if (send_netlink_message < 0){
perror("sendmsg");
close(netlink_route_socket);
exit(-1);
}
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_name = (void *)&sa;
msg.msg_namelen = sizeof(sa);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
while(nb_addr_added < 3){
receive_netlink_message = recvmsg(netlink_route_socket, &msg, 0);
p_netlink_message_header_received = (struct nlmsghdr *)buff;
if(receive_netlink_message < 0){
perror("recvmsg");
close(netlink_route_socket);
exit(-1);
}
for(p_netlink_message_header_received = (struct nlmsghdr *) buf;
NLMSG_OK (p_netlink_message_header_received,
receive_netlink_message);
p_netlink_message_header_received = NLMSG_NEXT (p_netlink_message_header_received,receive_netlink_message))
{
switch(p_netlink_message_header_received->nlmsg_type)
{
case RTM_NEWLINK:
printf("***** case RTM_NEWLINK *****\n");
p_ifinfomsg = NLMSG_DATA(p_netlink_message_header_received);
printf("ifi_family %d\n",p_ifinfomsg->ifi_family);
printf("ifi_type %4x\n",p_ifinfomsg->ifi_type);
printf("ifi_index %d\n",p_ifinfomsg->ifi_index);
printf("ifi_flags %x\n",p_ifinfomsg->ifi_flags);
printf("ifi_change %x\n",p_ifinfomsg->ifi_change);
break;
case RTM_DELLINK:
printf("***** case RTM_DELLINK *****\n");
break;
case RTM_GETLINK:
printf("***** case RTM_GETLINK *****\n");
break;
case RTM_NEWADDR:
printf("***** case RTM_NEWADDR *****\n");
printf("A new address has been configured\n");
nb_addr_added++;
p_rtattr = NLMSG_DATA(p_netlink_message_header_received);
p_ifaddrmsg = NLMSG_DATA(p_netlink_message_header_received);
printf("=> Routing Attributes\n");
printf("rta_len %d\n",p_rtattr->rta_len);
printf("rta_type %d\n",p_rtattr->rta_type);
printf("=> Interface Address informations\n");
printf("ifa_family %d\n",p_ifaddrmsg->ifa_family);
printf("ifa_prefixlen %d\n",p_ifaddrmsg->ifa_prefixlen);
printf("ifa_flags %x\n",p_ifaddrmsg->ifa_flags);
printf("ifa_scope %d\n",p_ifaddrmsg->ifa_scope);
printf("ifa_index %d\n",p_ifaddrmsg->ifa_index);
break;
case RTM_DELADDR:
printf("***** case RTM_DELADDR *****\n");
printf("An address has been deleted ?\n");
break;
case RTM_GETADDR:
printf("***** case RTM_GETADDR *****\n");
break;
default:
printf("Message type %d received\n",
p_netlink_message_header_received->nlmsg_type);
break;
}
}
}
printf("Coming out\n");
return(0);
} |
Partager