2424#include <stdlib.h>
2525#include <asm/types.h>
2626#include <sys/socket.h>
27- #include <netlink/addr.h>
28- #include <netlink/netlink.h>
29- #include <netlink/handlers.h>
30- #include <netlink/route/link.h>
31- #include <netlink/route/addr.h>
32- #include <arpa/inet.h>
3327#include <assert.h>
3428#include <errno.h>
29+ #include "etherinfo_struct.h"
3530#include "etherinfo.h"
3631
3732/*
3833 *
3934 * Internal functions for working with struct etherinfo
4035 *
4136 */
42-
43- inline struct etherinfo * new_etherinfo_record ()
44- {
45- struct etherinfo * ptr ;
46-
47- ptr = malloc (sizeof (struct etherinfo )+1 );
48- if ( ptr ) {
49- memset (ptr , 0 , sizeof (struct etherinfo )+1 );
50- }
51-
52- return ptr ;
53- }
54-
55-
5637void free_etherinfo (struct etherinfo * ptr )
5738{
5839 if ( ptr == NULL ) { // Just for safety
@@ -82,6 +63,13 @@ void free_etherinfo(struct etherinfo *ptr)
8263 *
8364 */
8465
66+ #define SET_STR_VALUE (dst , src ) { \
67+ if( dst ) { \
68+ free(dst); \
69+ }; \
70+ dst = strdup(src); \
71+ }
72+
8573static void callback_nl_link (struct nl_object * obj , void * arg )
8674{
8775 struct etherinfo * ethi = (struct etherinfo * ) arg ;
@@ -110,7 +98,7 @@ static void callback_nl_link(struct nl_object *obj, void *arg)
11098 ptr += 3 ;
11199 }
112100 }
113- ethi -> hwaddress = strdup ( hwaddr );
101+ SET_STR_VALUE ( ethi -> hwaddress , hwaddr );
114102}
115103
116104
@@ -137,16 +125,16 @@ static void callback_nl_address(struct nl_object *obj, void *arg)
137125 struct nl_addr * brdcst = rtnl_addr_get_broadcast ((struct rtnl_addr * )obj );
138126 char brdcst_str [66 ];
139127
140- ethi -> ipv4_address = strdup ( ip_str );
128+ SET_STR_VALUE ( ethi -> ipv4_address , ip_str );
141129 ethi -> ipv4_netmask = rtnl_addr_get_prefixlen ((struct rtnl_addr * ) obj );
142130
143131 if ( brdcst ) {
144132 memset (& brdcst_str , 0 , 66 );
145133 inet_ntop (family , nl_addr_get_binary_addr (brdcst ), (char * )& brdcst_str , 64 );
146- ethi -> ipv4_broadcast = strdup ( brdcst_str );
134+ SET_STR_VALUE ( ethi -> ipv4_broadcast , brdcst_str );
147135 }
148136 } else {
149- ethi -> ipv6_address = strdup ( ip_str );
137+ SET_STR_VALUE ( ethi -> ipv6_address , ip_str );
150138 ethi -> ipv6_netmask = rtnl_addr_get_prefixlen ((struct rtnl_addr * ) obj );
151139 }
152140 return ;
@@ -186,70 +174,59 @@ void dump_etherinfo(FILE *fp, struct etherinfo *ptr)
186174 fprintf (fp , "\n" );
187175}
188176
189- struct etherinfo * get_etherinfo (const char * ifdevname )
177+
178+ int get_etherinfo (struct etherinfo * ethinf , struct _nlconnection * nlc , nlQuery query )
190179{
191- struct etherinfo * ethinf = NULL ;
192- struct nl_handle * handle ;
193180 struct nl_cache * link_cache ;
194181 struct nl_cache * addr_cache ;
195182 struct rtnl_addr * addr ;
196183 struct rtnl_link * link ;
197- int ifindex ;
198-
199- /* Establish connection to NETLINK */
200- handle = nl_handle_alloc ();
201- nl_connect (handle , NETLINK_ROUTE );
202-
203- /* Find the interface index we're looking up */
204- link_cache = rtnl_link_alloc_cache (handle );
205- ifindex = rtnl_link_name2i (link_cache , ifdevname );
206- if ( ifindex < 0 ) {
207- return NULL ;
208- }
209-
210- /* Create an empty record, where ethernet information will be saved */
211- ethinf = new_etherinfo_record ();
212- if ( !ethinf ) {
213- return NULL ;
214- }
215- ethinf -> index = ifindex ;
216- ethinf -> device = strdup (ifdevname ); /* Should extract via libnl - nl_link callback? */
217-
218- /* Extract MAC/hardware address of the interface */
219- link = rtnl_link_alloc ();
220- rtnl_link_set_ifindex (link , ifindex );
221- nl_cache_foreach_filter (link_cache , (struct nl_object * )link , callback_nl_link , ethinf );
222- rtnl_link_put (link );
223- nl_cache_free (link_cache );
224-
225- /* Extract IP address information */
226- addr_cache = rtnl_addr_alloc_cache (handle );
227- addr = rtnl_addr_alloc ();
228- rtnl_addr_set_ifindex (addr , ifindex );
229- nl_cache_foreach_filter (addr_cache , (struct nl_object * )addr , callback_nl_address , ethinf );
230- rtnl_addr_put (addr );
231- nl_cache_free (addr_cache );
232-
233- /* Close NETLINK connection */
234- nl_close (handle );
235- nl_handle_destroy (handle );
236-
237- return ethinf ;
238- }
184+ int ret = 0 ;
239185
240- #ifdef TESTPROG
241- // Simple standalone test program
242- int main (int argc , char * * argv ) {
243- struct etherinfo * inf = NULL ;
244-
245- inf = get_etherinfo (argv [1 ]);
246- if ( inf == NULL ) {
247- fprintf (stderr , "Operation failed. Could not retrieve ethernet information\n" );
248- exit (2 );
186+ if ( !ethinf || !nlc ) {
187+ return 0 ;
249188 }
250- dump_etherinfo (stdout , inf );
251- free_etherinfo (inf );
252189
253- return 0 ;
190+ /* Find the interface index we're looking up.
191+ * As we don't expect it to change, we're reusing a "cached"
192+ * interface index if we have that
193+ */
194+ if ( ethinf -> index < 0 ) {
195+ link_cache = rtnl_link_alloc_cache (nlc -> nlrt_handle );
196+ ethinf -> index = rtnl_link_name2i (link_cache , ethinf -> device );
197+ if ( ethinf -> index < 0 ) {
198+ return 0 ;
199+ }
200+ nl_cache_free (link_cache );
201+ }
202+
203+ /* Query the for requested info vai NETLINK */
204+ switch ( query ) {
205+ case NLQRY_LINK :
206+ /* Extract MAC/hardware address of the interface */
207+ link_cache = rtnl_link_alloc_cache (nlc -> nlrt_handle );
208+ link = rtnl_link_alloc ();
209+ rtnl_link_set_ifindex (link , ethinf -> index );
210+ nl_cache_foreach_filter (link_cache , (struct nl_object * )link , callback_nl_link , ethinf );
211+ rtnl_link_put (link );
212+ nl_cache_free (link_cache );
213+ ret = 1 ;
214+ break ;
215+
216+ case NLQRY_ADDR :
217+ /* Extract IP address information */
218+ addr_cache = rtnl_addr_alloc_cache (nlc -> nlrt_handle );
219+ addr = rtnl_addr_alloc ();
220+ rtnl_addr_set_ifindex (addr , ethinf -> index );
221+ nl_cache_foreach_filter (addr_cache , (struct nl_object * )addr , callback_nl_address , ethinf );
222+ rtnl_addr_put (addr );
223+ nl_cache_free (addr_cache );
224+ ret = 1 ;
225+ break ;
226+
227+ default :
228+ ret = 0 ;
229+ }
230+ return ret ;
254231}
255- #endif
232+
0 commit comments