Skip to content

Instantly share code, notes, and snippets.

@jitomesky
Created June 6, 2015 05:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jitomesky/a3204946092bacef1993 to your computer and use it in GitHub Desktop.
Save jitomesky/a3204946092bacef1993 to your computer and use it in GitHub Desktop.
DHCPv6サーバーにIPv6 Prefixくれくれするスクリプト(注: まともなDHCPv6クライアントではないです.隔離環境で実行してください)
import ipaddress
import sys
import socket
import os
# ref
# http://docs.python.jp/3/library/socket.html
def show_identifier(option):
if option[1] == 1:
print("client identifier DUID: ",end="")
else:
print("server identifier DUID: ",end="")
# print DUID
print("0x",end="")
print("".join("%02x" % i for i in option[4:]))
return
def show_prefix(option):
iaid = int.from_bytes(option[4:8], byteorder="big", signed=False)
T1 = int.from_bytes(option[8:12], byteorder="big", signed=False)
T2 = int.from_bytes(option[12:16], byteorder="big", signed=False)
# parse IA Prefix
pdopt_type = int.from_bytes(option[16:18], byteorder="big", signed=False)
if pdopt_type != 26:
print("Prefix Delegation Option type: %d not supported" % pdopt_type)
return
pdopt_len = int.from_bytes(option[18:20], byteorder="big", signed=False)
pereferred_lifetime = int.from_bytes(option[20:24], byteorder="big", signed=False)
valid_lifetime = int.from_bytes(option[24:28], byteorder="big", signed=False)
prefix_length = int.from_bytes(option[28:29], byteorder="big", signed=False)
# print prefix
prefix = option[29:]
for i,x in enumerate(prefix):
if i != 0 and i % 2 == 0:
print(":", end="")
print("%02x" % x, end="")
print("/%d" % prefix_length)
return
dhv6_client = 546
dhv6_server = 547
BUF_MAX = 512
duid = [0x00,0x01,0x00,0x01,0x1c,0xfb,0x53,0xac,0x08,0x00,0x27,0x42,0xa9,0xd9]
s = None
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s.bind(("::1", dhv6_client))
# create dhcpv6 packet
# message type(8bit)
dhv6_mes = bytearray([1]) # Solicit
# transaction id(24bit)
dhv6_mes += os.urandom(1)
dhv6_mes += os.urandom(1)
dhv6_mes += os.urandom(1)
# Option: Client Identifier
# option code(16bit)
opt_cliident = bytearray([0,1])
# option length(16bit)
opt_cliident += bytearray([0,len(duid)])
# set client duid
opt_cliident += bytearray(duid)
# Option: Indentity Association for Prefix Delegation
iaid = [0x00] * 4
t1 = [0x00] * 4
t2 = [0x00] * 4
opt_iapd_val = iaid + t1 + t2
# option code(16bit)
opt_iapd = bytearray([0,25])
# option length(16bit)
opt_iapd += bytearray([0,len(opt_iapd_val)])
# set client duid
opt_iapd += bytearray(opt_iapd_val)
dhv6_mes += opt_cliident
dhv6_mes += opt_iapd
# send Solicit packet
s.sendto(dhv6_mes, ("ff02::1:2", dhv6_server))
# recv DHCPv6 packet from Server
recv = bytearray([0] * BUF_MAX)
r = s.recvfrom_into(recv)
rlen = r[0]
# split DHCPv6 options
dhv6_head = recv[:4]
dhv6_options = []
i = 4
while i < rlen:
# get option length
optlen = int.from_bytes(recv[i+2:i+4], byteorder="big", signed=False)
# get value
opt = recv[i:i+4+optlen]
dhv6_options.append(opt)
i += 4 + optlen
# parse DHCPv6
for option in dhv6_options:
# check option type
opt_type = int.from_bytes(option[:2], byteorder="big", signed=False)
if opt_type in [1,2]:
show_identifier(option)
continue
# if opt_type == 23:
# show_dns(option)
# continue
if opt_type == 25:
show_prefix(option)
continue
print("option code %d not supported" % opt_type)
s.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment