Raw sockets and sendto in python

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-03 02:22:37

I ended up deciding that Raw Sockets are just to bugged to be usable. Especially since this software needs to be cross platform, quirks for OSX may not be applicable to other OSs.

For the time being I simply wrapped the "sockets" that are provided by scapy. In the future I will write something that only depends on libdnet (as that is what scapy does to write raw frames).

You can find this implemented here:

https://github.com/hellais/txscapy

cox

An IP header is required to have a multiple of 32 bits to be valid. And there is also a padding area on the end.

So depending on the IP options set in the header — which occupies a variable amount of bits — one needs to count bits and padding.

Looks like different OSes handle this differently. One might consider that a clever OS would do this padding for you.

0.0.0.0 doesn't look like a valid IP source address to me. Does changing this to any other value make any difference?

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> from scapy.all import IP, TCP
WARNING: No route found for IPv6 destination :: (no default route?)
>>> pkt = IP(src='0.0.0.0', dst='127.0.0.1')/TCP()
>>> spkt1 = str(pkt)
>>> 
>>> outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
>>> outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
>>> outs.sendto(spkt1, ('127.0.0.1', 0))
40

I don't seem to have any error writing that specific set of packets - I'm using x86_64 with a 2.6.38-* Gnu/Linux kernel.

Perhaps your issue is related to some Mac OS X brain damage with raw sockets?

Another related issue. Python impacket module has ping.py script to ping hosts. On Mac OS X Lion I got an error while using this script:

Traceback (most recent call last):
  File "/private/var/www/env/bin/ping.py", line 73, in <module>
    s.sendto(ip.get_packet(), (dst, 0))
socket.error: [Errno 22] Invalid argument

But on Ubuntu everything works fine and I am getting replies from hosts.

I have no hard evidence, but I think this might be related to the ethernet minimum payload size.

From wikipedia:

The minimum payload is 42 octets when 802.1Q tag is present and 46 octets when absent.

Your first example packet was only 40 bytes, so it'd be below the limit in either case. You could experiment with changing the padding from 20 bytes to those values to verify that it stops working at one of the limits.

If so, the behavior makes perfect sense; the OS is rejecting the packet because you aren't giving it enough data to construct a valid packet.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!