Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Use Raw Socket in Python?

I am writing an application to test a network driver for handling corrupted data. And I thought of sending this data using raw socket, so it will not be corrected by the sending machine's TCP-IP stack.

I am writing this application solely on Linux. I have code examples of using raw sockets in system-calls, but I would really like to keep my test as dynamic as possible, and write most if not all of it in Python.

I have googled the web a bit for explanations and examples of the usage of raw sockets in python, but haven't found anything really enlightening. Just a a very old code example that demonstrates the idea, but in no means work.

From what I gathered, Raw Socket usage in Python is nearly identical in semantics to UNIX's raw socket, but without the structs that define the packets structure.

I was wondering if it would even be better not to write the raw socket part of the test in Python, but in C with system-calls, and call it from the main Python code?

like image 773
Avihu Turzion Avatar asked Jul 13 '09 06:07

Avihu Turzion


2 Answers

You do it like this:

First you disable your network card's automatic checksumming:

sudo ethtool -K eth1 tx off 

And then send your dodgy frame from python 2 (You'll have to convert to Python 3 yourself):

#!/usr/bin/env python from socket import socket, AF_PACKET, SOCK_RAW s = socket(AF_PACKET, SOCK_RAW) s.bind(("eth1", 0))  # We're putting together an ethernet frame here,  # but you could have anything you want instead # Have a look at the 'struct' module for more  # flexible packing/unpacking of binary data # and 'binascii' for 32 bit CRC src_addr = "\x01\x02\x03\x04\x05\x06" dst_addr = "\x01\x02\x03\x04\x05\x06" payload = ("["*30)+"PAYLOAD"+("]"*30) checksum = "\x1a\x2b\x3c\x4d" ethertype = "\x08\x01"  s.send(dst_addr+src_addr+ethertype+payload+checksum) 

Done.

like image 127
brice Avatar answered Sep 19 '22 08:09

brice


Sockets system calls (or Winsocks, on Windows), are already wrapped in the standard module socket: intro, reference.

I've never used raw sockets but it looks like they can be used with this module:

The last example shows how to write a very simple network sniffer with raw sockets on Windows. The example requires administrator privileges to modify the interface:

import socket  # the public network interface HOST = socket.gethostbyname(socket.gethostname())  # create a raw socket and bind it to the public interface s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) s.bind((HOST, 0))  # Include IP headers s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)  # receive all packages s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)  # receive a package print s.recvfrom(65565)  # disabled promiscuous mode s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 
like image 38
Bastien Léonard Avatar answered Sep 20 '22 08:09

Bastien Léonard