libtins python interface?

575 views
Skip to first unread message

bbdo

unread,
Aug 14, 2014, 7:13:08 PM8/14/14
to lib...@googlegroups.com
Greetings - is anyone using the python interface? I am able to decode packets but am not able to send packets that I have constructed. I get errors similar to this:

Boost.Python.ArgumentError: Python argument types in

    PacketSender.isend(PacketSender, str, Boost.Python.class)

did not match C++ signature:

    isend(PyPacketSender {lvalue}, Tins::NetworkInterface, PyPDU*)

Yet I can re-send the sniffed packets on a different interface without issue. I can also change various attributes such as the dest/source MAC addresses.


thanks!

Matias Fontanini

unread,
Aug 14, 2014, 7:26:18 PM8/14/14
to lib...@googlegroups.com
Hi,

the python bindings are not at all usable. Some features might work, but there are still lots that aren't working and there are a few bugs. It's just a project I started a while ago but never really got into. 

It's in my plans to start developing again though, since according to some quick benchmarks I made, it was several times faster than the rest of the python libraries available. 

If you really want to use python for this, I'd suggest dpkt. If you're ok with C++, then go for libtins :D.

Cheers

Brad Doctor

unread,
Aug 14, 2014, 9:24:50 PM8/14/14
to Matias Fontanini, lib...@googlegroups.com

Yes it seems that this could replace most Python libs that need basic packet crafting but at high speed. Very appealing! Happy to assist if possible.

--
You received this message because you are subscribed to a topic in the Google Groups "libtins" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/libtins/t006uGJK5Wg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to libtins+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Diego Hurtado Pimentel

unread,
Jun 15, 2015, 11:17:06 AM6/15/15
to lib...@googlegroups.com
Hello there

Great job with Tins library, Matías!

I am trying to add Python bindings with Python using Cython but right now I'm stuck with several errors. Where can I find the Python interface that is being discussed here?
Maybe I have better luck using this one.

Thanks and regards

Matias Fontanini

unread,
Jun 15, 2015, 12:18:46 PM6/15/15
to lib...@googlegroups.com, diegoh...@gmail.com
That python interface is here. It's been a lot of time since I touched that code, so I don't really remember in which state it is. It's developed using boost python in C++, which makes it run pretty fast. There's already a lot of function wrappers, which make it really simple to generate all setters/getters for PDUs.

Let me know if you need any help with this. It would be pretty nice to have a working python wrapper :D

Diego Hurtado Pimentel

unread,
Jun 15, 2015, 1:23:13 PM6/15/15
to lib...@googlegroups.com, diegoh...@gmail.com

Thanks, I got the files, unzipped them, changed directory to pytins-master and ran make. This is the output:

In file included from include/pypdu.h:103:0,
                 
from include/pydhcp.h:33,
                 
from src/pydhcp.cpp:31:
src
/pydhcp.cpp: In static member function static void PyDHCP::python_register()’:
include
/cppwrappers.h:325:65: error: no matches converting function routers to type class std::list<Tins::IPv4Address> (class Tins::DHCP::*)()const
     make_getter_wrapper
((RETURN (CLASS::*)() const)(&CLASS::NAME))
                                                                 
^
include
/cppwrappers.h:353:23: note: in expansion of macro PYTINS_GETTER_FUN
     
.def("get_"#NAME, PYTINS_GETTER_FUN(GETTER_TYPE, CLASS, NAME)) \
                       
^
src
/pydhcp.cpp:80:9: note: in expansion of macro PYTINS_MAKE_GETTER_SETTER2
         PYTINS_MAKE_GETTER_SETTER2
(std::list<ipaddress_type>, const std::list<ipaddress_type>&, DHCP, routers)
         
^
In file included from src/pydhcp.cpp:30:0:
/usr/local/include/tins/dhcp.h:411:37: note: candidates are: std::vector<Tins::IPv4Address> Tins::DHCP::routers() const
         std
::vector<ipaddress_type> routers() const;
                                     
^
/usr/local/include/tins/dhcp.h:293:14: note:                 void Tins::DHCP::routers(const std::vector<Tins::IPv4Address>&)
         
void routers(const std::vector<ipaddress_type> &routers);
             
^
In file included from include/pypdu.h:103:0,
                 
from include/pydhcp.h:33,
                 
from src/pydhcp.cpp:31:
include
/cppwrappers.h:331:64: error: no matches converting function routers to type void (class Tins::DHCP::*)(const class std::list<Tins::IPv4Address>&)’
     make_setter_wrapper
((void (CLASS::*)(ARGTYPE))(&CLASS::NAME))
                                                               
^
include
/cppwrappers.h:354:23: note: in expansion of macro PYTINS_SETTER_FUN
     
.def("set_"#NAME, PYTINS_SETTER_FUN(SETTER_TYPE, CLASS, NAME))
                       
^
src
/pydhcp.cpp:80:9: note: in expansion of macro PYTINS_MAKE_GETTER_SETTER2
         PYTINS_MAKE_GETTER_SETTER2
(std::list<ipaddress_type>, const std::list<ipaddress_type>&, DHCP, routers)
         
^
In file included from src/pydhcp.cpp:30:0:
/usr/local/include/tins/dhcp.h:411:37: note: candidates are: std::vector<Tins::IPv4Address> Tins::DHCP::routers() const
         std
::vector<ipaddress_type> routers() const;
                                     
^
/usr/local/include/tins/dhcp.h:293:14: note:                 void Tins::DHCP::routers(const std::vector<Tins::IPv4Address>&)
         
void routers(const std::vector<ipaddress_type> &routers);
             
^
In file included from include/pypdu.h:103:0,
                 
from include/pydhcp.h:33,
                 
from src/pydhcp.cpp:31:
include
/cppwrappers.h:325:65: error: no matches converting function domain_name_servers to type class std::list<Tins::IPv4Address> (class Tins::DHCP::*)()const
     make_getter_wrapper
((RETURN (CLASS::*)() const)(&CLASS::NAME))
                                                                 
^
include
/cppwrappers.h:353:23: note: in expansion of macro PYTINS_GETTER_FUN
     
.def("get_"#NAME, PYTINS_GETTER_FUN(GETTER_TYPE, CLASS, NAME)) \
                       
^
src
/pydhcp.cpp:81:9: note: in expansion of macro PYTINS_MAKE_GETTER_SETTER2
         PYTINS_MAKE_GETTER_SETTER2
(std::list<ipaddress_type>, const std::list<ipaddress_type>&, DHCP, domain_name_servers)
         
^
In file included from src/pydhcp.cpp:30:0:
/usr/local/include/tins/dhcp.h:422:37: note: candidates are: std::vector<Tins::IPv4Address> Tins::DHCP::domain_name_servers() const
         std
::vector<ipaddress_type> domain_name_servers() const;
                                     
^
/usr/local/include/tins/dhcp.h:302:14: note:                 void Tins::DHCP::domain_name_servers(const std::vector<Tins::IPv4Address>&)
         
void domain_name_servers(const std::vector<ipaddress_type> &dns);
             
^
In file included from include/pypdu.h:103:0,
                 
from include/pydhcp.h:33,
                 
from src/pydhcp.cpp:31:
include
/cppwrappers.h:331:64: error: no matches converting function domain_name_servers to type void (class Tins::DHCP::*)(const class std::list<Tins::IPv4Address>&)’
     make_setter_wrapper
((void (CLASS::*)(ARGTYPE))(&CLASS::NAME))
                                                               
^
include
/cppwrappers.h:354:23: note: in expansion of macro PYTINS_SETTER_FUN
     
.def("set_"#NAME, PYTINS_SETTER_FUN(SETTER_TYPE, CLASS, NAME))
                       
^
src
/pydhcp.cpp:81:9: note: in expansion of macro PYTINS_MAKE_GETTER_SETTER2
         PYTINS_MAKE_GETTER_SETTER2
(std::list<ipaddress_type>, const std::list<ipaddress_type>&, DHCP, domain_name_servers)
         
^
In file included from src/pydhcp.cpp:30:0:
/usr/local/include/tins/dhcp.h:422:37: note: candidates are: std::vector<Tins::IPv4Address> Tins::DHCP::domain_name_servers() const
         std
::vector<ipaddress_type> domain_name_servers() const;
                                     
^
/usr/local/include/tins/dhcp.h:302:14: note:                 void Tins::DHCP::domain_name_servers(const std::vector<Tins::IPv4Address>&)
         
void domain_name_servers(const std::vector<ipaddress_type> &dns);
             
^
make
: *** [src/pydhcp.o] Error 1

Is there something obvious that I'm missing?

Matias Fontanini

unread,
Jun 15, 2015, 1:48:10 PM6/15/15
to lib...@googlegroups.com, diegoh...@gmail.com
By looking at the error message, I think that DHCP::routers returned at some point a std::list and now it returns a vector (keep in mind that the last time I touched that code base, libtins was not even on version 1.0, so some stuff was changed since then). I think the fix should be fairly simple, and involves changing:

PYTINS_MAKE_GETTER_SETTER2(std::list<ipaddress_type>, const std::list<ipaddress_type>&, DHCP, routers)

To:

PYTINS_MAKE_GETTER_SETTER2(std::vector<ipaddress_type>, const std::vector<ipaddress_type>&, DHCP, routers)

Didn't try this but it should work.
...

houbaastef

unread,
Jul 31, 2015, 10:41:39 PM7/31/15
to libtins
Hello,

i started to work on a cython wrapper for libtins (scapy and dpkt are just too slow...). I have some difficulties with C++ classes inheritance and template methods, but i don't think it will be an insurmountable problem. I'll post update here when it will be usable, probably in a few weeks.

Regards,
Stephane

Matias Fontanini

unread,
Aug 1, 2015, 12:43:09 AM8/1/15
to libtins
Hi Stephane,

that's awesome! Looking forward to hearing news about it :). Let me know if you need any help on anything.

Cheers,
Matias

houbaastef .

unread,
Aug 6, 2015, 4:46:39 PM8/6/15
to Matias Fontanini, libtins
(WIP: it can kill your pets or trigger the end of the world or worse)

https://github.com/stephane-martin/cycapture

What would be nice in libtins to ease the bindings:
- a way to remove an option from IP and TCP PDU (so that i can write things like "tcp_pdu.mss = None" in python to reset the option)
- a non-templated function to find PDUs inside a PDU, because template support in python is a bit too rough

eg like:
PDU* cpp_find_pdu(const PDU* pdu, PDU::PDUType t) {
PDU* current_pdu = (PDU*) pdu;
while(current_pdu) {
if(current_pdu->matches_flag(t))
return current_pdu;
current_pdu = current_pdu->inner_pdu();
}
return 0;
}
- default constructors for address ranges... gcc is painful about it.



- have been implemented: generic PDU, RAW, Ethernet, IP, TCP, UDP (the DNS is just a stub). It should be enough to test the parsing capabilities.
- polymorphism of find_pdu has been workaround: there is a PDU.find_pdu method that does the same job. Just have to specify the type of PDU you're looking for.
- i think i was quite careful about memory management, but of course some small details can still be wrong
- the setup.py will download and compile deps (libpcap and libtins). the python extensions are built statically against them. so the resulting .so should be all you need in python.


Cheers,
Stephane



--
You received this message because you are subscribed to the Google Groups "libtins" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libtins+u...@googlegroups.com.

Matias Fontanini

unread,
Aug 6, 2015, 11:53:36 PM8/6/15
to libtins, matias.f...@gmail.com
Nice! Looks interesting, I'll have a look at it soon.

On Thursday, August 6, 2015 at 1:46:39 PM UTC-7, houbaastef wrote:
(WIP: it can kill your pets or trigger the end of the world or worse)

https://github.com/stephane-martin/cycapture

What would be nice in libtins to ease the bindings:
- a way to remove an option from IP and TCP PDU (so that i can write things like "tcp_pdu.mss = None" in python to reset the option)

I have been avoiding doing this for a while but I guess it's time to do it (this involves doing the same on several PDUs, not just IP and TCP).
 
- a non-templated function to find PDUs inside a PDU, because template support in python is a bit too rough

You can already do this. You can explicitly instantiate the function using PDU as the template parameter:

PDU* tcp = packet.find_pdu<PDU>(TCP::pdu_flag);

 Haven't tested that, but it should work.


eg like:
PDU* cpp_find_pdu(const PDU* pdu, PDU::PDUType t) {
PDU* current_pdu = (PDU*) pdu;
while(current_pdu) {
if(current_pdu->matches_flag(t))
return current_pdu;
current_pdu = current_pdu->inner_pdu();
}
return 0;
}
- default constructors for address ranges... gcc is painful about it.

Sounds good!
 



- have been implemented: generic PDU, RAW, Ethernet, IP, TCP, UDP (the DNS is just a stub). It should be enough to test the parsing capabilities.
- polymorphism of find_pdu has been workaround: there is a PDU.find_pdu method that does the same job. Just have to specify the type of PDU you're looking for.
- i think i was quite careful about memory management, but of course some small details can still be wrong
- the setup.py will download and compile deps (libpcap and libtins). the python extensions are built statically against them. so the resulting .so should be all you need in python.


Cheers,
Stephane


2015-08-01 6:43 GMT+02:00 Matias Fontanini <matias.f...@gmail.com>:
Hi Stephane,

that's awesome! Looking forward to hearing news about it :). Let me know if you need any help on anything.

Cheers,
Matias


On Friday, July 31, 2015 at 7:41:39 PM UTC-7, houbaastef wrote:
Hello,

i started to work on a cython wrapper for libtins (scapy and dpkt are just too slow...). I have some difficulties with C++ classes inheritance and template methods, but i don't think it will be an insurmountable problem. I'll post update here when it will be usable, probably in a few weeks.

Regards,
Stephane

On Friday, 15 August 2014 01:26:18 UTC+2, Matias Fontanini wrote:
Hi,

the python bindings are not at all usable. Some features might work, but there are still lots that aren't working and there are a few bugs. It's just a project I started a while ago but never really got into. 

It's in my plans to start developing again though, since according to some quick benchmarks I made, it was several times faster than the rest of the python libraries available. 

If you really want to use python for this, I'd suggest dpkt. If you're ok with C++, then go for libtins :D.

Cheers


--
You received this message because you are subscribed to the Google Groups "libtins" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libtins+unsubscribe@googlegroups.com.

houbaastef .

unread,
Aug 9, 2015, 8:08:33 PM8/9/15
to Matias Fontanini, libtins
I forgot one thing: please provide a base exception class that all libtins specific exceptions inherit from. This is needed to provide a useful fallback in bindings, when you will add more granular exceptions to libtins.

(I can open tickets on github if you want to track desirable enhancements).

Thanks,
Stephane

To unsubscribe from this group and stop receiving emails from it, send an email to libtins+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "libtins" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libtins+u...@googlegroups.com.

Matias Fontanini

unread,
Aug 17, 2015, 7:38:39 PM8/17/15
to libtins, matias.f...@gmail.com
I just pushed a remove_option member function on IP, TCP and the rest of the PDUs that have options. Docs are not pushed yet, but you can have a look at the source code. Usage would be something like

TCP tcp;
tcp
.mss(1460);
tcp
.remove_option(TCP::MSS);

I'll work on the rest of the stuff you mentioned soon. I'll keep you updated.
To unsubscribe from this group and stop receiving emails from it, send an email to libtins+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "libtins" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libtins+unsubscribe@googlegroups.com.

Matias Fontanini

unread,
Aug 18, 2015, 1:43:20 AM8/18/15
to libtins, matias.f...@gmail.com
Okay, pushed the common exception type thing too :)

Robert Gomułka

unread,
Sep 30, 2015, 10:19:26 AM9/30/15
to libtins, matias.f...@gmail.com
Hi all,
the performance of pure C++ code looks great (http://libtins.github.io/benchmark/).
But what about Python wrapper? How fast it is? Is there huge performance drop?

Regards,
Robert

houbaastef .

unread,
Sep 30, 2015, 10:43:23 AM9/30/15
to Robert Gomułka, libtins, Matias Fontanini
For my python wrapper, it's a bit early to make perf measures. I still haven't finished the wrapping classes (lacking the 802.11 stuff).

But basically the python wrapping just manages python objects that encapsulates the C++ objects, and delegates all operations to C++. So the overhead is limited to python object management.That should be very small.

I should release a beta version in a few days.

Note: No windows support.

Regards,
Stephane


--
You received this message because you are subscribed to the Google Groups "libtins" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libtins+u...@googlegroups.com.

Robert Gomułka

unread,
Sep 30, 2015, 10:55:50 AM9/30/15
to houbaastef ., libtins, Matias Fontanini
"Note: No windows support."

Why not?

Regards,
Robert

houbaastef .

unread,
Sep 30, 2015, 10:59:50 AM9/30/15
to Robert Gomułka, libtins, Matias Fontanini
- just focusing on *nix for now.
- i don't have a windows licence...
- i use pthread library to provide a non-blocking pcap wrappers

Matt

unread,
Nov 21, 2016, 1:17:30 PM11/21/16
to libtins
Is there an update on this? What happened to the work being done?
Reply all
Reply to author
Forward
0 new messages