The system provides a Python object for input DHCPv6 packet: alc.dhcpv6
alc.dhcpv6 has following attributes to represent the DHCPv6 header fields:
Table: DHCPv6 header fields displays DHCPv6 header fields.
Class attributes | DHCPv6 header field | Client/server msg | Relay msg | Access |
---|---|---|---|---|
alc.dhcpv6.pkt_len |
Integer, Total length of original DHCPv4 packet(UDP/IP header excluded) in bytes |
✓ | ✓ | Read |
alc.dhcpv6.msg_type |
msg-type |
✓ | ✓ | Read |
alc.dhcpv6.transaction_id |
transaction-id |
✓ | Read |
|
alc.dhcpv6.hop_count |
hop-count |
✓ | read/write |
|
alc.dhcpv6.link_addr |
link-address |
✓ | read/write |
|
alc.dhcpv6.peer_addr |
peer-address |
✓ | read/write |
All header fields (as the attribute of alc.dhcpv6 class) are strings (except pkt_len) with exact bytes as it appears in the packet.
If the attribute does not exist in the specified msg-type, for example if the link_attr does not exist in client/server message(C/S msg), then its value should be None.
The following is a list of all functions in the class:
alc.dhcpv6.drop()
alc.dhcpv6. getOptionList()
alc.dhcpv6. get(op-code)
alc.dhcpv6. set(op-code,valTuple)
alc.dhcpv6. clear(op-code)
alc.dhcpv6.get_iana() / alc.dhcpv6.set_iana(OPDL)
alc.dhcpv6.get_iata() / alc.dhcpv6.set_iata(OPDL)
alc.dhcpv6.get_vendoropts() / alc.dhcpv6.set_vendoropts(OPDL)
alc.dhcpv6.get_iapd() / alc.dhcpv6.set_iapd(OPDL)
alc.dhcpv6.get_relaymsg()
alc.dhcpv6.set_relaymsg(packet)
alc.dhcpv6. drop(): The system drops the resulting packet.
alc.dhcpv6. getOptionList(): Returns a tuple that includes the option-code of the existing top level DHCPv6 options in the packet. The order of the element in the tuple is as same as the options appear in the packet. If there are multiple instances of same option, then each instance is one element in the tuple. For example:
A C/S Msg with Elapsed Time/Client Identifier/IANA/FQDN/Vendor Class/Option Request returns (8,1,3,39,16,6).
A Relay Msg with Relay Message option only returns (9)
alc.dhcpv6. get(op-code): Returns a tuple that includes all instances of the specified top level option as string The value of this string is the exact bytes of the option as it appears in packet (excludes option-code and option-len). If the specified option does not exist in the input packet, then it returns ().
Examples:
If there is a Status Code option in the packet, status-code 0 and status-msg:”Address Assigned”; then alc.dhcpv6.get(13) should return: (‛\x00\x00Address Assigned’,)
alc.dhcpv6. set(op-code,valTuple): This function removes all the existing instances of the specified top level option and insert a list of new options. Each element in valTuple is a string, representing one instance of the new option to be inserted. For each new option, the option-code is specified in op-code, the option-len is the length of the element, reset of option is the element itself.
To insert a Status Code options with status-code 0 and status-msg:”Address Assigned”; use alc.dhcpv6.set(13, (‛\x00\x00Address Assigned’,))
alc.dhcpv6. clear(op-code): This function removes all the existing instances of specified top level option.
Although alc.dhcpv6.get() and alc.dhcpv6.set() provide a generic way to manipulate DHCPv6 top level options, but some DHCPv6 options have more complex/hierarchical structure like IA_NA/IA_TA, and so on. To provide a friendly access to these kinds of options, the system provides the following options specific functions:
alc.dhcpv6.get_iana() / alc.dhcpv6.set_iana(OPDL)
alc.dhcpv6.get_iata() / alc.dhcpv6.set_iata(OPDL)
alc.dhcpv6.get_vendoropts() / alc.dhcpv6.set_vendoropts(OPDL)
alc.dhcpv6.get_iapd() / alc.dhcpv6.set_iapd(OPDL)
All alc.dhcpv6.get_XXX() returns a data structure:‟OPDL” (Option Data structure List)
OPDL is a list. Each element in the list represents an instance of that option. For example, if there are 3 IANA in the packet, then get_iana() returns a list of 3 elements, each element represent one instance of IANA option in the packet.
Each element in OPDL is a list, referred to as ‟OPD” in this list.
Each element in OPD represent one field in the option(option-code and option-len are not included), the order of the element is as same as the fields appear in the option
For field that could be parsed into sub-option by RFC, then the element is a dict, the key of this dict is the sub-option type, if sub-option is one of following supported-sub-option, the value to the key is a sub-option_OPDL represent the list of that specific sub-option
IAADDR(5)
Status Code(13)
IAPREFIX(26)
Else, if the sub-option is not one of the above, then the value to the key is a list of string of sub-option-data, each string represent one instance of the sub-option.
The structure of sub-option_OPDL of IAADDR is: [[v6_addr,prefer_lifetime, valid_lifetime,sub-option_OPDL], ]
The structure of sub-option_OPDL of Status Code is: [[status-code,status-msg], and so on]
The structure of sub-option_OPDL of IAPREFIX is: [[prefer_lifetime,valid_lifetime,prefix-len,v6prefix,sub-option_OPDL],..]
For the field (by RFC definition) could be parsed into sub-options, but it does not actually exist, then the dict is empty {}
For field that cannot be parsed into sub-option by RFC, the element is a string of exact bytes of that field
All alc.dhcpv6.set_XX(OPDL) accepts an OPDL as the parameter. Remove all existing instances of the corresponding options and then insert new options represented by the specified OPDL.
alc.dhcpv6.get_iana()/alc.dhcpv6.get_iana(OPDL)
The general OPDL structure for these two functions is: [[IAID_val,T1_val,T2_val, sub-option_dict]]
The structure of sub-option_dict is:{sub-option-type:sub-option_val}
If sub-option is supported-sub-option, then sub-option_val is a sub-option_OPDL
For all other sub-options, the sub-option_val is a list of string of sub-option-data
Examples:
For a packet with an IANA option as in Figure: :
The option-data is (hex formatted)
‟0f:f0:de:f1:00:02:a3:00:00:04:38:00:00:05:00:18:20:01:05:58:60:45:00:47:45:cc:d9:f2:57:27:ea:e0:00:05:46:00:00:05:46:00”
The following is an example script:
import alc
iana_list=alc.dhcpv6.get_iana()
#iana_list will be [['\x0f\xf0\xde\xf1','\x00\x02\xa3\x00','\x00\x04\\x38\x00',{5:[['\x20\x01\x05\x58\x60\x45\x00\x47\x45\xcc\xd9\xf2\x57\x27\xea\xe0','\x00\x05\x46\x00','\x00\x05\x46\x00',{}]]}]]
iana_list[0][1]='\x00\x00\x04\xb0' #change T1 to 1200
alc.dhcpv6.set_iana(iana_list)#update the iana
alc.dhcpv6.get_iata()/alc.dhcpv6.get_iata(OPDL)
The general OPDL structure for these two functions is: [[IAID_val, sub-option_dict]]
The structure of sub-option_dict is:{sub-option-type:sub-option_val}
If sub-option is supported-sub-option, then sub-option_val is a sub-option_OPDL
For all other sub-options, the sub-option_val is a list of string of sub-option-data
Examples: These two function are very similar with IANA, so the examples are skipped here.
alc.dhcpv6.get_iapd()/alc.dhcpv6.get_iapd(OPDL)
The general OPDL structure for these two functions is: [[IAID_val,T1_va1,T2_val, sub-option_dict]]
The structure of sub-option_dict is:{sub-option-type:sub-option_val}
If sub-option is supported-sub-option, then sub-option_val is a sub-option_OPDL
For all other sub-options, the sub-option_val is a list of string of sub-option-data
The option-data is (hex formatted)
‟00:00:00:01:00:00:07:08:00:00:0b:40:00:1a:00:19:00:00:0e:10:00:01:51:80:38:20:01:0d:b8:00:02:00:00:00:00:00:00:00:00:00:00”
Following is an example script:
import alc
iapd_list=alc.dhcpv6.get_iapd()
#iapd_list will be [['\x00\x00\x00\x01','\x00\x00\x07\x08','\x00\x00\x0b\x40',{26:[['\x00\x00\x0e\x10','\x00\x01\x51\x80','\x38', '\x20\x01\x0d\xb8\x00\x02\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00',{}]]}]]
iapd_list[0][1]='\x00\x00\x04\xb0' #change T1 to 1200
alc.dhcpv6.set_iapd(iapd_list)#update the iapd
alc.dhcpv6.get_vendoropts()/alc.dhcpv6.get_vendoropts (OPDL)
The general OPDL structure for these two functions is: [[enterpriseid_val, sub-option_dict]]
The structure of sub-option_dict is:{sub-option-type:sub-option_val}
If sub-option is supported-sub-option, then sub-option_val is a sub-option_OPDL
For all other sub-options, the sub-option_val is a list of string of sub-option-data
Examples: For a packet with vendor options as in Figure: :
The option-data is (hex formatted)
‟00:00:19:7f:00:01:00:09:69:61:2d:6e:61:5f:30:30:31:00:02:00:09:69:61:2d:70:64:5f:30:30:31:00:03:00:01:38:00:04:00:01:40”
The following is an example script:
import alc
vendoropts_list=alc.dhcpv6.get_vendoropts()
# vendoropts_list will be [['\x00\x00\x19\x7f', {1:['\x69\x61\x2d\x6e\x61\x5f\x30\x30\x31'],2:[ '\x69\x61\x2d\x70\x64\x5f\x30\x30\x31'],3:['\x38'], 4:['\x40']}]]
iapd_list[0][1][4][0]='\x60' #change sub-option 4’s value to 0x60
alc.dhcpv6.set_vendoropts(vendoropts_list)#update the vendor options
For DHCPv6 relay message, the ‟Relay Message” option embedded a full DHCPv6 packet and the embedded packet could itself have a ‟Replay Message” option which embedded another DHCPv6 packet.
To provide direct access to embedded DHCPv6 packet, the system provides following functions:
alc.dhcpv6.get_relaymsg()
alc.dhcpv6.set_relaymsg(packet)
alc.dhcpv6. get_relaymsg(): This function returns a populated alc.dhcpv6 object. which means the returned object was initialized with the DHCPv6 packet embedded in ‟Relay Message” option as the input.
alc.dhcpv6. set_relaymsg(packet): This function accepts an alc.dhcpv6 object as a parameter. This object replaces existing ‟Relay Message” option.
Example-1 script for single relay message:
import alc
#input packet is a relay-reply msg
embed_dhcpv6_packet=alc.dhcpv6.get_relaymsg()
iana_list=embed_dhcpv6_packet.get_iana()
iana_list[0][1]='\x00\x00\x04\xb0' #change T1 to 1200
embed_dhcpv6_packet.set_iana(iana_list)#update the iana of the embedded packet
alc.dhcpv6.set_relaymsg(embed_dhcpv6_packet)#update the Relay Message option
Example-2 script for double relay message (relay of relay):
import alc
#input packet is a relay-reply msg
embed_lv1_packet=alc.dhcpv6.get_relaymsg() #get the level=1 embedded packet
embed_lv2_packet= embed_lv1_packet.get_relaymsg()#get level-2 packet embedded in level-1 packet
iana_list=embed_dhcpv6_packet.get_iana()
iana_list[0][1]='\x00\x00\x04\xb0' #change T1 to 1200
embed_dhcpv6_packet.set_iana(iana_list)#update the iana
embed_lv1_packet.set_relaymsg(embed_lv2_packet)#update the Relay Message option of lv1 msg
alc.dhcpv6.set_relaymsg(embed_lv1_packet)#update the Relay Message option of the top level msg