Created
June 6, 2015 05:10
-
-
Save jitomesky/a3204946092bacef1993 to your computer and use it in GitHub Desktop.
DHCPv6サーバーにIPv6 Prefixくれくれするスクリプト(注: まともなDHCPv6クライアントではないです.隔離環境で実行してください)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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