@@ -116,6 +116,7 @@ def _dhcp6_dispatcher(x, *args, **kargs):
116116 41 : "OPTION_NEW_POSIX_TIMEZONE" , # RFC4833
117117 42 : "OPTION_NEW_TZDB_TIMEZONE" , # RFC4833
118118 48 : "OPTION_LQ_CLIENT_LINK" , # RFC5007
119+ 56 : "OPTION_NTP_SERVER" , # RFC5908
119120 59 : "OPT_BOOTFILE_URL" , # RFC5970
120121 60 : "OPT_BOOTFILE_PARAM" , # RFC5970
121122 61 : "OPTION_CLIENT_ARCH_TYPE" , # RFC5970
@@ -174,6 +175,7 @@ def _dhcp6_dispatcher(x, *args, **kargs):
174175 # 46: "DHCP6OptLQClientTime", #RFC5007
175176 # 47: "DHCP6OptLQRelayData", #RFC5007
176177 48 : "DHCP6OptLQClientLink" , # RFC5007
178+ 56 : "DHCP6OptNTPServer" , # RFC5908
177179 59 : "DHCP6OptBootFileUrl" , # RFC5790
178180 60 : "DHCP6OptBootFileParam" , # RFC5970
179181 61 : "DHCP6OptClientArchType" , # RFC5970
@@ -961,6 +963,60 @@ class DHCP6OptLQClientLink(_DHCP6OptGuessPayload): # RFC5007
961963 length_from = lambda pkt : pkt .optlen )]
962964
963965
966+ class DHCP6NTPSubOptSrvAddr (Packet ): # RFC5908 sect 4.1
967+ name = "DHCP6 NTP Server Address Suboption"
968+ fields_desc = [ShortField ("optcode" , 1 ),
969+ ShortField ("optlen" , 16 ),
970+ IP6Field ("addr" , "::" )]
971+
972+ def extract_padding (self , s ):
973+ return b"" , s
974+
975+
976+ class DHCP6NTPSubOptMCAddr (Packet ): # RFC5908 sect 4.2
977+ name = "DHCP6 NTP Multicast Address Suboption"
978+ fields_desc = [ShortField ("optcode" , 2 ),
979+ ShortField ("optlen" , 16 ),
980+ IP6Field ("addr" , "::" )]
981+
982+ def extract_padding (self , s ):
983+ return b"" , s
984+
985+
986+ class DHCP6NTPSubOptSrvFQDN (Packet ): # RFC5908 sect 4.3
987+ name = "DHCP6 NTP Server FQDN Suboption"
988+ fields_desc = [ShortField ("optcode" , 3 ),
989+ FieldLenField ("optlen" , None , length_of = "fqdn" ),
990+ DNSStrField ("fqdn" , "" ,
991+ length_from = lambda pkt : pkt .optlen )]
992+
993+ def extract_padding (self , s ):
994+ return b"" , s
995+
996+
997+ _ntp_subopts = {1 : DHCP6NTPSubOptSrvAddr ,
998+ 2 : DHCP6NTPSubOptMCAddr ,
999+ 3 : DHCP6NTPSubOptSrvFQDN }
1000+
1001+
1002+ def _ntp_subopt_dispatcher (p , ** kwargs ):
1003+ cls = conf .raw_layer
1004+ if len (p ) >= 2 :
1005+ o = struct .unpack ("!H" , p [:2 ])[0 ]
1006+ cls = _ntp_subopts .get (o , conf .raw_layer )
1007+ return cls (p , ** kwargs )
1008+
1009+
1010+ class DHCP6OptNTPServer (_DHCP6OptGuessPayload ): # RFC5908
1011+ name = "DHCP6 NTP Server Option"
1012+ fields_desc = [ShortEnumField ("optcode" , 56 , dhcp6opts ),
1013+ FieldLenField ("optlen" , None , length_of = "ntpserver" ,
1014+ fmt = "!H" ),
1015+ PacketListField ("ntpserver" , [],
1016+ _ntp_subopt_dispatcher ,
1017+ length_from = lambda pkt : pkt .optlen )]
1018+
1019+
9641020class DHCP6OptBootFileUrl (_DHCP6OptGuessPayload ): # RFC5970
9651021 name = "DHCP6 Boot File URL Option"
9661022 fields_desc = [ShortEnumField ("optcode" , 59 , dhcp6opts ),
0 commit comments