]> The Tcpdump Group git mirrors - libpcap/commitdiff
Add support for libnl 2.x, adapted from a newer version of the iw command.
authorGuy Harris <[email protected]>
Sun, 14 Nov 2010 01:42:47 +0000 (17:42 -0800)
committerGuy Harris <[email protected]>
Sun, 14 Nov 2010 01:42:47 +0000 (17:42 -0800)
config.h.in
configure
configure.in
pcap-linux.c

index f988e8f09d90481f26e2a3fb3fd361a5ffc4b908..3b9ce3c96ad573de405383cf291bda34f882b83a 100644 (file)
@@ -52,6 +52,9 @@
 /* if libnl exists */
 #undef HAVE_LIBNL
 
 /* if libnl exists */
 #undef HAVE_LIBNL
 
+/* if libnl exists and is version 2.x */
+#undef HAVE_LIBNL_2_x
+
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
index e85d87e4bc72213b2c187d9cb645b56ce27387eb..c204a8720b37e0397b91e073549979dfcb04d9f7 100755 (executable)
--- a/configure
+++ b/configure
@@ -7341,7 +7341,93 @@ fi
 
 
        if test x$with_libnl != xno ; then
 
 
        if test x$with_libnl != xno ; then
-               { echo "$as_me:$LINENO: checking for nl_handle_alloc in -lnl" >&5
+               #
+               # Try libnl 2.x first.
+               #
+               { echo "$as_me:$LINENO: checking for nl_socket_alloc in -lnl" >&5
+echo $ECHO_N "checking for nl_socket_alloc in -lnl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nl_nl_socket_alloc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char nl_socket_alloc ();
+int
+main ()
+{
+return nl_socket_alloc ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_nl_nl_socket_alloc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_nl_nl_socket_alloc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nl_nl_socket_alloc" >&5
+echo "${ECHO_T}$ac_cv_lib_nl_nl_socket_alloc" >&6; }
+if test $ac_cv_lib_nl_nl_socket_alloc = yes; then
+
+                       #
+                       # Yes, we have libnl 2.x.
+                       #
+                       LIBS="-lnl-genl -lnl $LIBS"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBNL 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBNL_2_x 1
+_ACEOF
+
+
+else
+
+                       #
+                       # No, we don't; do we have libnl 1.x?
+                       #
+                       { echo "$as_me:$LINENO: checking for nl_handle_alloc in -lnl" >&5
 echo $ECHO_N "checking for nl_handle_alloc in -lnl... $ECHO_C" >&6; }
 if test "${ac_cv_lib_nl_nl_handle_alloc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 echo $ECHO_N "checking for nl_handle_alloc in -lnl... $ECHO_C" >&6; }
 if test "${ac_cv_lib_nl_nl_handle_alloc+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -7403,18 +7489,30 @@ fi
 { echo "$as_me:$LINENO: result: $ac_cv_lib_nl_nl_handle_alloc" >&5
 echo "${ECHO_T}$ac_cv_lib_nl_nl_handle_alloc" >&6; }
 if test $ac_cv_lib_nl_nl_handle_alloc = yes; then
 { echo "$as_me:$LINENO: result: $ac_cv_lib_nl_nl_handle_alloc" >&5
 echo "${ECHO_T}$ac_cv_lib_nl_nl_handle_alloc" >&6; }
 if test $ac_cv_lib_nl_nl_handle_alloc = yes; then
-  LIBS="-lnl $LIBS"
+
+                               #
+                               # Yes.
+                               #
+                               LIBS="-lnl $LIBS"
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_LIBNL 1
 _ACEOF
 
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_LIBNL 1
 _ACEOF
 
+
 else
 else
-  if test x$with_libnl = xyes ; then
-                               { { echo "$as_me:$LINENO: error: libnl support requested but libnl not found" >&5
+
+                               #
+                               # No, we don't have libnl at all.
+                               #
+                               if test x$with_libnl = xyes ; then
+                                       { { echo "$as_me:$LINENO: error: libnl support requested but libnl not found" >&5
 echo "$as_me: error: libnl support requested but libnl not found" >&2;}
    { (exit 1); exit 1; }; }
 echo "$as_me: error: libnl support requested but libnl not found" >&2;}
    { (exit 1); exit 1; }; }
-                       fi
+                               fi
+
+fi
+
 
 fi
 
 
 fi
 
index d71d3fd188c8dd9bfd9b63f2e8f459708368ac71..3c1cedfbfb884e8601f5f2a7c72f0db83e4910ae 100644 (file)
@@ -445,13 +445,39 @@ linux)
                with_libnl=$withval,,)
 
        if test x$with_libnl != xno ; then
                with_libnl=$withval,,)
 
        if test x$with_libnl != xno ; then
-               AC_CHECK_LIB(nl, nl_handle_alloc,
-                       LIBS="-lnl $LIBS"
-                       AC_DEFINE(HAVE_LIBNL,1,[if libnl exists]),
-                       if test x$with_libnl = xyes ; then
-                               AC_MSG_ERROR([libnl support requested but libnl not found])
-                       fi
-               )
+               #
+               # Try libnl 2.x first.
+               #
+               AC_CHECK_LIB(nl, nl_socket_alloc,
+               [
+                       #
+                       # Yes, we have libnl 2.x.
+                       #
+                       LIBS="-lnl-genl -lnl $LIBS"
+                       AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
+                       AC_DEFINE(HAVE_LIBNL_2_x,1,[if libnl exists and is version 2.x])
+               ],
+               [
+                       #
+                       # No, we don't; do we have libnl 1.x?
+                       #
+                       AC_CHECK_LIB(nl, nl_handle_alloc,
+                       [
+                               #
+                               # Yes.
+                               #
+                               LIBS="-lnl $LIBS"
+                               AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
+                       ],
+                       [
+                               #
+                               # No, we don't have libnl at all.
+                               #
+                               if test x$with_libnl = xyes ; then
+                                       AC_MSG_ERROR([libnl support requested but libnl not found])
+                               fi
+                       ])
+               ])
        fi
 
        AC_LBL_TPACKET_STATS
        fi
 
        AC_LBL_TPACKET_STATS
index f8b3f106c572178808fd5ccf3e2e49304462118d..deabbc4a986a2232d9515207e259c7f6d70ce47d 100644 (file)
@@ -527,8 +527,37 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
        return 1;
 }
 
        return 1;
 }
 
+#ifndef HAVE_LIBNL_2_x
+/* libnl 2.x compatibility code */
+
+#define nl_sock nl_handle
+
+static inline struct nl_handle *
+nl_socket_alloc(void)
+{
+       return nl_handle_alloc();
+}
+
+static inline void
+nl_socket_free(struct nl_handle *h)
+{
+       nl_handle_destroy(h);
+}
+
+static inline int
+__genl_ctrl_alloc_cache(struct nl_handle *h, struct nl_cache **cache)
+{
+       struct nl_cache *tmp = genl_ctrl_alloc_cache(h);
+       if (!tmp)
+               return -ENOMEM;
+       *cache = tmp;
+       return 0;
+}
+#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache
+#endif /* !HAVE_LIBNL_2_x */
+
 struct nl80211_state {
 struct nl80211_state {
-       struct nl_handle *nl_handle;
+       struct nl_sock *nl_sock;
        struct nl_cache *nl_cache;
        struct genl_family *nl80211;
 };
        struct nl_cache *nl_cache;
        struct genl_family *nl80211;
 };
@@ -536,23 +565,26 @@ struct nl80211_state {
 static int
 nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
 {
 static int
 nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
 {
-       state->nl_handle = nl_handle_alloc();
-       if (!state->nl_handle) {
+       int err;
+
+       state->nl_sock = nl_socket_alloc();
+       if (!state->nl_sock) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: failed to allocate netlink handle", device);
                return PCAP_ERROR;
        }
 
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: failed to allocate netlink handle", device);
                return PCAP_ERROR;
        }
 
-       if (genl_connect(state->nl_handle)) {
+       if (genl_connect(state->nl_sock)) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: failed to connect to generic netlink", device);
                goto out_handle_destroy;
        }
 
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                    "%s: failed to connect to generic netlink", device);
                goto out_handle_destroy;
        }
 
-       state->nl_cache = genl_ctrl_alloc_cache(state->nl_handle);
-       if (!state->nl_cache) {
+       err = genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache);
+       if (err < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
-                   "%s: failed to allocate generic netlink cache", device);
+                   "%s: failed to allocate generic netlink cache: %s",
+                   device, strerror(-err));
                goto out_handle_destroy;
        }
 
                goto out_handle_destroy;
        }
 
@@ -568,7 +600,7 @@ nl80211_init(pcap_t *handle, struct nl80211_state *state, const char *device)
 out_cache_free:
        nl_cache_free(state->nl_cache);
 out_handle_destroy:
 out_cache_free:
        nl_cache_free(state->nl_cache);
 out_handle_destroy:
-       nl_handle_destroy(state->nl_handle);
+       nl_socket_free(state->nl_sock);
        return PCAP_ERROR;
 }
 
        return PCAP_ERROR;
 }
 
@@ -577,7 +609,7 @@ nl80211_cleanup(struct nl80211_state *state)
 {
        genl_family_put(state->nl80211);
        nl_cache_free(state->nl_cache);
 {
        genl_family_put(state->nl80211);
        nl_cache_free(state->nl_cache);
-       nl_handle_destroy(state->nl_handle);
+       nl_socket_free(state->nl_sock);
 }
 
 static int
 }
 
 static int
@@ -605,7 +637,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
 
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, mondevice);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
 
-       err = nl_send_auto_complete(state->nl_handle, msg);
+       err = nl_send_auto_complete(state->nl_sock, msg);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
@@ -626,7 +658,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
                        return PCAP_ERROR;
                }
        }
                        return PCAP_ERROR;
                }
        }
-       err = nl_wait_for_ack(state->nl_handle);
+       err = nl_wait_for_ack(state->nl_sock);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
@@ -685,7 +717,7 @@ del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
                    0, NL80211_CMD_DEL_INTERFACE, 0);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
 
                    0, NL80211_CMD_DEL_INTERFACE, 0);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
 
-       err = nl_send_auto_complete(state->nl_handle, msg);
+       err = nl_send_auto_complete(state->nl_sock, msg);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
@@ -706,7 +738,7 @@ del_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
                        return PCAP_ERROR;
                }
        }
                        return PCAP_ERROR;
                }
        }
-       err = nl_wait_for_ack(state->nl_handle);
+       err = nl_wait_for_ack(state->nl_sock);
        if (err < 0) {
                if (err == -ENFILE) {
                        /*
        if (err < 0) {
                if (err == -ENFILE) {
                        /*