Skip to content

Instantly share code, notes, and snippets.

@refraction-ray
Last active May 2, 2022 16:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save refraction-ray/a5c91a77632738c09a53ff4e4dc1dd92 to your computer and use it in GitHub Desktop.
Save refraction-ray/a5c91a77632738c09a53ff4e4dc1dd92 to your computer and use it in GitHub Desktop.
extension functions on IPOption settings in scapy
  • Remarks

The realization of these IP options is based on RFC 791. But support for these IP options from ISP is by no means guaranteed. Especially, lssr and ssrr options are the most interesting ones but are generally forbidden by ISP's routers. I don't write the implementation on security options since I think it is of no use (correct me if I am wrong). For details on IP headers and settings, see my blog (in Chinese).

  • Usage example:
IP(dst='some.ip1', options=IPOption(lsrr('some.ip2','some.ip3')))/ICMP()
IP(dst=some.ip, ttl=64,IPOption(record_route(9))/ICMP() 
IP(dst=some.ip, src=fake.ip, IPOption(timestamp(3,2,'stamp.ip.1','stamp.ip.2'))/ICMP()
from scapy.all import sr1, IP, IPOption,ICMP
import ipaddress as ipa
def record_route(hop=1):
if hop >= 10:
raise Exception('exceed the max length of ip header')
length = chr(hop*4+3)
option_head = b'\x07'+length.encode()+b'\x04'
route_data = "".join(['\x00']*4*hop)
option = option_head+('%s'%route_data).encode()
return option
def lsrr(*source_route_table):
hop = len(source_route_table)
if hop >= 10:
raise Exception('exceed the max length of ip header')
length = chr(hop*4+3)
option_head = b'\x83'+length.encode()+b'\x04'
option = option_head
for ip in source_route_table:
ip = ipa.v4_int_to_packed(int(ipa.IPv4Address(ip)))
option = option + ip
return option
def ssrr(*source_route_table):
hop = len(source_route_table)
if hop >= 10:
raise Exception('exceed the max length of ip header')
length = chr(hop*4+3)
option_head = b'\x89'+length.encode()+b'\x04'
option = option_head
for ip in source_route_table:
ip = ipa.v4_int_to_packed(int(ipa.IPv4Address(ip)))
option = option + ip
return option
def timestamp(flag=0,hop=1,*specified_route):
if flag == 0:
if hop >= 10:
raise Exception('exceed the max length of ip header')
length = chr (hop*4+4)
option_head = b'\x44'+length.encode()+b'\x05\x00'
route_data = "".join(['\x00']*4*hop)
option = option_head+('%s'%route_data).encode()
return option
if flag == 1:
if hop >= 5:
raise Exception('exceed the max length of ip header')
length = chr (hop*8+4)
option_head = b'\x44'+length.encode()+b'\x05\x01'
route_data = "".join(['\x00']*8*hop)
option = option_head+('%s'%route_data).encode()
return option
if flag==3:
hop_check = len(specified_route)
if hop_check != hop:
raise Exception('the number of routes is not consistent with hops')
if hop >= 5:
raise Exception('exceed the max length of ip header')
length = chr (hop*8+4)
option_head = b'\x44'+length.encode()+b'\x05\x03'
option = option_head
for ip in specified_route:
ip = ipa.v4_int_to_packed(int(ipa.IPv4Address(ip)))
option = option + ip + b'\x00\x00\x00\x00'
return option
raise Exception('no such flag, flag must be set as 0,1,3 in timastamp option')
def streamid(byte_id):
return b'\x88\x04'+byte_id
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment