Git Product home page Git Product logo

libnl's Introduction

libnl

A port of libnl, a collection of libraries providing APIs to the Netlink protocol based Linux kernel interfaces. This library is API-equivalent to the original C library, and should make it relatively easy to convert C programs into pure Python without having to call external binaries.

As Netlink is a Linux-specific protocol, this library will only work on Linux hosts. All communication is done using sockets between the Python process and the Linux kernel. The main driver for porting libnl was to use nl80211 in Python to scan for wireless access points natively, without having to run an external program and parse its output.

  • Python 2.6, 2.7, PyPy, PyPy3, 3.3, and 3.4 supported on Linux.

Build Status WiFi

Build Status

Coverage Status

Latest Version

Downloads

Quickstart

Install:

pip install libnl

Example Implementations

A simple Python program that merely lists network adapters on the host:

import ctypes
import socket

from libnl.error import errmsg
from libnl.handlers import NL_CB_CUSTOM, NL_CB_VALID, NL_OK
from libnl.linux_private.if_link import IFLA_IFNAME, IFLA_RTA
from libnl.linux_private.netlink import NETLINK_ROUTE, NLMSG_LENGTH, NLM_F_DUMP, NLM_F_REQUEST
from libnl.linux_private.rtnetlink import RTA_DATA, RTA_NEXT, RTA_OK, RTM_GETLINK, ifinfomsg, rtgenmsg
from libnl.misc import get_string
from libnl.msg import nlmsg_data, nlmsg_hdr
from libnl.nl import nl_connect, nl_recvmsgs_default, nl_send_simple
from libnl.socket_ import nl_socket_alloc, nl_socket_modify_cb


def callback(msg, _):
    nlh = nlmsg_hdr(msg)
    iface = ifinfomsg(nlmsg_data(nlh))
    hdr = IFLA_RTA(iface)
    remaining = ctypes.c_int(nlh.nlmsg_len - NLMSG_LENGTH(iface.SIZEOF))
    while RTA_OK(hdr, remaining):
        if hdr.rta_type == IFLA_IFNAME:
            print('Found interface {0}: {1}'.format(iface.ifi_index, get_string(RTA_DATA(hdr)).decode('ascii')))
        hdr = RTA_NEXT(hdr, remaining)
    return NL_OK


sk = nl_socket_alloc()  # Creates an nl_sock instance.
ret = nl_connect(sk, NETLINK_ROUTE)  # Create file descriptor and bind socket.
if ret < 0:
    raise RuntimeError('nl_connect() returned {0} ({1})'.format(ret, errmsg[abs(ret)]))
rt_hdr = rtgenmsg(rtgen_family=socket.AF_PACKET)
ret = nl_send_simple(sk, RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP, rt_hdr, rt_hdr.SIZEOF)
if ret < 0:
    raise RuntimeError('nl_send_simple() returned {0} ({1})'.format(ret, errmsg[abs(ret)]))
nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, callback, None)  # Add callback to the nl_sock instance.
ret = nl_recvmsgs_default(sk)  # Get kernel's answer, and call attached callbacks.
if ret < 0:
    raise RuntimeError('nl_recvmsgs_default() returned {0} ({1})'.format(ret, errmsg[abs(ret)]))

Here are some more examples with their C equivalents in order from "easy" to "hard":

Changelog

This project adheres to Semantic Versioning.

0.2.0 - 2015-03-26

Added
  • Python2.6, PyPy, and PyPy3 support.

0.1.1 - 2015-03-15

  • Initial release.

libnl's People

Contributors

robpol86 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

libnl's Issues

Implement linked lists.

Much simpler to just implement the same thing the C library uses, especially when porting new features in the future.

incompatible to python3.6

Installed using: pip3 install --upgrade --user git+https://github.com/Robpol86/libnl
Test with python 3.6.8 (on Ubuntu 18.04):

$ python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from libnl.nl import nl_recvmsgs_default, nl_send_auto
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sebastian/.local/lib/python3.6/site-packages/libnl/nl.py", line 25, in <module>
    from libnl.handlers import (NL_CB_ACK, nl_cb_clone, NL_CB_CUSTOM, NL_CB_DUMP_INTR, NL_CB_FINISH, NL_CB_INVALID,
  File "/home/sebastian/.local/lib/python3.6/site-packages/libnl/handlers.py", line 18, in <module>
    from libnl.msg import nl_msg_dump, nl_nlmsg_flags2str, nl_nlmsgtype2str, nlmsg_hdr
  File "/home/sebastian/.local/lib/python3.6/site-packages/libnl/msg.py", line 19, in <module>
    import libnl.linux_private.netlink
  File "/home/sebastian/.local/lib/python3.6/site-packages/libnl/linux_private/netlink.py", line 11, in <module>
    from libnl.misc import (bytearray_ptr, c_int, c_uint, c_uint16, c_uint32, c_ushort, SIZEOF_INT, SIZEOF_U16, SIZEOF_U32,
  File "/home/sebastian/.local/lib/python3.6/site-packages/libnl/misc.py", line 54, in <module>
    c_int = _class_factory(ctypes.c_int)
  File "/home/sebastian/.local/lib/python3.6/site-packages/libnl/misc.py", line 16, in _class_factory
    class ClsPyPy(base):
TypeError: __class__ set to <class 'libnl.misc._class_factory.<locals>.ClsPyPy'> defining 'ClsPyPy' as <class 'libnl.misc._class_factory.<locals>.ClsPyPy'>

I'm no python pro, thus I cannot fix it myself.

scan trigger without sudo

Hi,
Is it possible to perform a scan trigger and disconnect without root permissions? I tried setting the udev rules for wlan0 to be MODE 0666, but this only allows reading of current AP/signal statuses without sudo.

get_vht_capa and get_vht_oper raise NotImplementedError

These functions raise a NotImplementedError meaning that if a network with those features (VHT capabilities and VHT operation) is within scanning range the nl_recvmsgs will fail, not allowing one to receive the rest of the data. It seems a better solution may be to return a dictionary (I think that is what those ieprinter functions return) that indicates it is not implemented and thus the remainder of the data still be retrieved.

Complete documentation.

Go over debug environment variables and logging. Create sphinx docs and put them on readthedocs or something.

KeyError exception in nl.py

There is a bug when initializing the callback dictionary. When the kernel sends a NLM_F_DUMP_INTR flag this exception occurs:

File "/usr/lib/python2.7/site-packages/libnl/nl.py", line 462, in recvmsgs
if cb.cb_set[NL_CB_DUMP_INTR]:
KeyError: 10

Is the following patch the correct fix?

--- handlers-0.2.0.py 2015-10-13 15:46:32.479024312 -0400
+++ handlers.py 2015-10-13 15:46:37.935024458 -0400
@@ -160,7 +160,7 @@
return None
cb = nl_cb()
cb.cb_active = NL_CB_TYPE_MAX + 1

  • for i in range(NL_CB_TYPE_MAX):
  • for i in range(NL_CB_TYPE_MAX + 1):
    nl_cb_set(cb, i, kind, None, None)
    nl_cb_err(cb, kind, None, None)
    return cb

How to check the NL80211_ATTR_SUPPORTED_IFTYPES attribute?

I am trying to use Python to determine whether a wireless card supports AP mode. I started with example_show_wifi_interface.py, and I thought I would be able to add a bit of code like this to the callback() function right before it prints:

if tb[nl80211.NL80211_ATTR_SUPPORTED_IFTYPES]:
    iftypes = nla_get_u32(tb[NL80211_ATTR_SUPPORTED_IFTYPES])
    rem = c_int()
    ap_mode = False
    for subattr in nla_for_each_nested(tb[iftypes], rem):
        if subattr == nl80211.NL80211_IFTYPE_AP:
            ap_mode = True
            break
    table.table_data.append(['Supports AP mode', str(ap_mode)])
else:
    print("Couldn't get attribute NL80211_ATTR_SUPPORTED_IFTYPES")

However, tb[nl80211.NL80211_ATTR_SUPPORTED_IFTYPES] is evaluating to None, and I don't know why, or even where to start looking for the right path forward. My first thought was to try to read some C code that uses the nl80211 library and model my Python on that, but the only thing I discovered was that I'm not enough of a C programmer to understand how iw is working internally :).

What am I doing wrong?

Auto-resolve bytearray_ptr for improved performance.

With lots of nla and genlmsghdr pointer gymnastics there's probably a lot of bytearray_ptr instances referencing another.

Have bytearray_ptr's init() method resolve incoming bytearray_ptrs and have it reference the root bytearray() directly.

Test unicode SSIDs.

Supposedly unicode can be used in SSIDs. Need to make sure libnl will handle it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.