1919 ByteEnumField ,
2020 ByteField ,
2121 ConditionalField ,
22+ FieldLenField ,
2223 FieldListField ,
2324 FixedPointField ,
2425 FlagsField ,
2829 LEIntField ,
2930 LEShortField ,
3031 MayEnd ,
32+ MultipleTypeField ,
3133 PacketField ,
3234 PacketLenField ,
3335 PacketListField ,
3739 StrField ,
3840 StrFixedLenEnumField ,
3941 StrFixedLenField ,
42+ StrLenField ,
4043 XByteField ,
4144 XStrFixedLenField ,
4245)
@@ -610,18 +613,6 @@ def __init__(self, details):
610613}
611614
612615
613- class NTPStatusPacket (Packet ):
614- """
615- Packet handling a non specific status word.
616- """
617-
618- name = "status"
619- fields_desc = [ShortField ("status" , 0 )]
620-
621- def extract_padding (self , s ):
622- return b"" , s
623-
624-
625616class NTPSystemStatusPacket (Packet ):
626617
627618 """
@@ -691,55 +682,6 @@ def extract_padding(self, s):
691682 return b"" , s
692683
693684
694- class NTPControlStatusField (PacketField ):
695- """
696- This field provides better readability for the "status" field.
697- """
698-
699- #########################################################################
700- #
701- # RFC 1305
702- #########################################################################
703- #
704- # Appendix B.3. Commands // ntpd source code: ntp_control.h
705- #########################################################################
706- #
707-
708- def m2i (self , pkt , m ):
709- ret = None
710- association_id = struct .unpack ("!H" , m [2 :4 ])[0 ]
711-
712- if pkt .err == 1 :
713- ret = NTPErrorStatusPacket (m )
714-
715- # op_code == CTL_OP_READSTAT
716- elif pkt .op_code == 1 :
717- if association_id != 0 :
718- ret = NTPPeerStatusPacket (m )
719- else :
720- ret = NTPSystemStatusPacket (m )
721-
722- # op_code == CTL_OP_READVAR
723- elif pkt .op_code == 2 :
724- if association_id != 0 :
725- ret = NTPPeerStatusPacket (m )
726- else :
727- ret = NTPSystemStatusPacket (m )
728-
729- # op_code == CTL_OP_WRITEVAR
730- elif pkt .op_code == 3 :
731- ret = NTPStatusPacket (m )
732-
733- # op_code == CTL_OP_READCLOCK or op_code == CTL_OP_WRITECLOCK
734- elif pkt .op_code == 4 or pkt .op_code == 5 :
735- ret = NTPClockStatusPacket (m )
736-
737- else :
738- ret = NTPStatusPacket (m )
739-
740- return ret
741-
742-
743685class NTPPeerStatusDataPacket (Packet ):
744686 """
745687 Packet handling the data field when op_code is CTL_OP_READSTAT
@@ -752,97 +694,87 @@ class NTPPeerStatusDataPacket(Packet):
752694 PacketField ("peer_status" , NTPPeerStatusPacket (), NTPPeerStatusPacket ),
753695 ]
754696
697+ def extract_padding (self , s ):
698+ return b"" , s
755699
756- class NTPControlDataPacketLenField (PacketLenField ):
757700
701+ class NTPControlStatusField (PacketField ):
758702 """
759- PacketField handling the "data " field of NTP control messages .
703+ The various types of the "status " field.
760704 """
761-
705+ # RFC 9327 sect 3
762706 def m2i (self , pkt , m ):
763- ret = None
764- if not m :
765- return ret
766-
767- # op_code == CTL_OP_READSTAT
768- if pkt .op_code == 1 :
769- if pkt .association_id == 0 :
770- # Data contains association ID and peer status
771- ret = NTPPeerStatusDataPacket (m )
772- else :
773- ret = conf .raw_layer (m )
774- else :
775- ret = conf .raw_layer (m )
776-
777- return ret
707+ association_id = struct .unpack ("!H" , m [2 :4 ])[0 ]
778708
779- def getfield (self , pkt , s ):
780- length = self .length_from (pkt )
781- i = None
782- if length > 0 :
783- # RFC 1305
784- # The maximum number of data octets is 468.
785- #
786- # include/ntp_control.h
787- # u_char data[480 + MAX_MAC_LEN]; /* data + auth */
788- #
789- # Set the minimum length to 480 - 468
790- length = max (12 , length )
791- if length % 4 :
792- length += (4 - length % 4 )
793- try :
794- i = self .m2i (pkt , s [:length ])
795- except Exception :
796- if conf .debug_dissector :
797- raise
798- i = conf .raw_layer (load = s [:length ])
799- return s [length :], i
709+ if pkt .err == 1 :
710+ return NTPErrorStatusPacket (m )
711+ elif pkt .op_code in [4 , 5 ]: # Read/write clock
712+ return NTPClockStatusPacket (m )
713+ else :
714+ if association_id != 0 :
715+ return NTPPeerStatusPacket (m )
716+ else :
717+ return NTPSystemStatusPacket (m )
800718
801719
802720class NTPControl (NTP ):
803721 """
804722 Packet handling NTP mode 6 / "Control" messages.
805723 """
806-
807- #########################################################################
808- #
809- # RFC 1305
810- #########################################################################
811- #
812- # Appendix B.3. Commands // ntpd source code: ntp_control.h
813- #########################################################################
814- #
815-
816- name = "Control message"
724+ deprecated_fields = {
725+ "status_word" : ("status" , "2.6.2" ),
726+ }
727+ # RFC 9327 sect 2
728+ name = "NTP Control message"
817729 match_subclass = True
818730 fields_desc = [
819- BitField ( "zeros " , 0 , 2 ),
731+ BitEnumField ( "leap " , 0 , 2 , _leap_indicator ),
820732 BitField ("version" , 2 , 3 ),
821733 BitEnumField ("mode" , 6 , 3 , _ntp_modes ),
822734 BitField ("response" , 0 , 1 ),
823735 BitField ("err" , 0 , 1 ),
824736 BitField ("more" , 0 , 1 ),
825737 BitEnumField ("op_code" , 0 , 5 , _op_codes ),
826738 ShortField ("sequence" , 0 ),
827- ConditionalField (NTPControlStatusField (
828- "status_word" , "" , Packet ), lambda p : p .response == 1 ),
829- ConditionalField (ShortField ("status" , 0 ), lambda p : p .response == 0 ),
739+ MultipleTypeField (
740+ [
741+ (
742+ ShortField ("status" , 0 ),
743+ lambda pkt : pkt .response == 0 or pkt .op_code in [6 , 7 ]
744+ )
745+ ],
746+ NTPControlStatusField ("status" , NTPSystemStatusPacket (), None ),
747+ ),
830748 ShortField ("association_id" , 0 ),
831749 ShortField ("offset" , 0 ),
832- ShortField ("count" , None ),
833- MayEnd (NTPControlDataPacketLenField (
834- "data" , "" , Packet , length_from = lambda p : p .count )),
750+ FieldLenField ("count" , None , length_of = "data" ),
751+ MayEnd (
752+ PadField (
753+ MultipleTypeField (
754+ # RFC 1305
755+ [
756+ (
757+ PacketListField (
758+ "data" ,
759+ "" ,
760+ NTPPeerStatusDataPacket ,
761+ length_from = lambda p : p .count ,
762+ ),
763+ lambda pkt : (
764+ pkt .response and
765+ pkt .op_code == 1 and
766+ pkt .association_id == 0
767+ )
768+ ),
769+ ],
770+ StrLenField ("data" , "" , length_from = lambda pkt : pkt .count ),
771+ ),
772+ align = 4
773+ )
774+ ),
835775 PacketField ("authenticator" , "" , NTPAuthenticator ),
836776 ]
837777
838- def post_build (self , p , pay ):
839- if self .count is None :
840- length = 0
841- if self .data :
842- length = len (self .data )
843- p = p [:11 ] + struct .pack ("!H" , length ) + p [13 :]
844- return p + pay
845-
846778
847779##############################################################################
848780# Private (mode 7)
0 commit comments