Bonjour à tous,

Je travaille en ce moment sur une fonction qui me permet de récupérer des notifications d'ajout ou de suppression d'adresses IP sur une interface (entre autres). La fonction en elle-même utilise des sockets netlink pour communiquer avec le kernel Linux, et j'utilise le protocole NETLINK_ROUTE puisque je communique directement avec la table de routage du kernel (et elle permet notamment de configurer des routes réseaux, des adresses IP, etc...).

Cette fonction en elle-même marche bien, et me remonte bien les events d'ajouts et de suppression d'adresses IP. Mais ce qui m'intéresserait aussi ce serait de pouvoir remonter l'adresse IP en elle-même, en même temps que l'évènement. J'ai consulté les manpages de netlink et de rtnetlink à ce sujet, mais tout ce que je parviens à faire c'est récupérer des informations relatives à l'adresse IP, pas l'adresse elle-même.

Ma question c'est : comment pourrais-je procéder pour obtenir l'adresse IP en utilisant des sockets netlink ? Je crois comprendre que c'est possible en soi, mais je peux me très bien me tromper T_T

Par ailleurs grâce au code de ptit_riton (le topic se situe plus bas), il est possible de bien récupérer des adresses IP configurées sur les interfaces ^_^. Ceci étant, j'aimerais pouvoir exploiter au maximum les sockets netlink, parce que je reste persuadé que ce doit être possible de le faire.

Voici le code de ma fonction utilisant les sockets netlink :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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);
}

Merci d'avance


KimKas