1+ #!/usr/bin/env python
2+ # -*- coding: utf-8 -*-
3+
14import socket , select , struct , time
25from .util import get_hw , to_str , protocol_to_ethertype , to_bytes
36
47class RawPacket ():
5- """RawPacket is the resulting data container.
8+ """RawPacket is the resulting data container of the RawSocket class .
69
710 It reads raw data and stores the MAC source, MAC destination, the Ethernet type and the data payload.
811
@@ -15,9 +18,17 @@ def __init__(self, data):
1518 foo (data): raw ethernet frame coming from the socket library, either **bytes in Python3** or **str in Python2**
1619 """
1720 self .dest = ""
21+ """(str/bytes/bytearray): destination
22+ """
1823 self .src = ""
24+ """(str/bytes/bytearray): source
25+ """
1926 self .type = ""
27+ """(str/bytes/bytearray): ethertype
28+ """
2029 self .data = ""
30+ """ = (str/bytes/bytearray): payload received, aka the msg sent on the other side
31+ """
2132 self .success = False
2233 try :
2334 self .dest , self .src , self .type = data [0 :6 ], data [6 :12 ], data [12 :14 ]
@@ -34,6 +45,19 @@ def __str__(self):
3445 return "" .join ([self .__repr__ (), ":\n " , self .data .decode ('utf-8' )])
3546
3647class RawSocket (object ):
48+ """RawSocket is using the socket library to send raw ethernet frames, using socket.RAW_SOCK
49+
50+ It has a similar API to the socket library: send/recv/close/dup.
51+
52+ Args:
53+ interface (str): the network interface to be used: wlp2s0, eth0, zt0, wlan0, ...
54+
55+ protocol (int): the ethertype to use: 0xEEAF for example [0 to 65535]
56+
57+ sock (socket.socket): If provided, this socket will be used for the communications
58+
59+ no_recv_protocol (bool): If True, the socket will not receive any data, for "sending only" sockets.
60+ """
3761 BROADCAST = "\xff \xff \xff \xff \xff \xff "
3862 def __init__ (self , interface , protocol , sock = None , no_recv_protocol = False ):
3963 if not 0x0000 < protocol < 0xFFFF :
@@ -51,6 +75,8 @@ def __init__(self, interface, protocol, sock=None, no_recv_protocol=False):
5175 self .close = self .sock .close
5276
5377 def dup (self ):
78+ """Duplicates the RawSocket
79+ """
5480 return RawSocket (self .interface , self .non_processed_protocol , self .sock .dup (), self .no_recv_protocol )
5581
5682 @staticmethod
@@ -61,12 +87,27 @@ def sock_create(interface, protocol, sock=None):
6187 return sock
6288
6389 def send (self , msg , dest = None , ethertype = None ):
90+ """Sends data through the socket.
91+
92+ Args:
93+ msg (str): Payload to be sent
94+
95+ dest (str/bytes/bytearray): recipient, if not mentioned it will be a broadcast example: "\xff \x12 \x32 \x34 \x41 " or bytes([255, 12, 32, 42, 43, 54])
96+
97+ ethertype (str/bytes/bytearray): Allow to send data using a different ethertype using the same socket. Default is the protocol given in the constructor.
98+ """
6499 if ethertype is None : ethertype = self .ethertype
65100 if dest is None : dest = self .BROADCAST
66101 payload = (to_bytes (dest ) + self .mac + to_bytes (ethertype ) + to_bytes (msg ))
67102 self .sock .send (payload )
68103
69104 def recv (self ):
105+ """Receive data from the socket on the protocol provided in the constructor
106+
107+ Blocks until data arrives. A timeout can be implemented using the socket timeout.
108+
109+ Returns RawPacket
110+ """
70111 data = self .sock .recv (1500 )
71112 return RawPacket (data )
72113
0 commit comments