<s> import abc <EOL> import struct <EOL> import six <EOL> import sys <EOL> import array <EOL> import binascii <EOL> from . import packet_base <EOL> from . import packet_utils <EOL> from ryu . lib import addrconv <EOL> from ryu . lib import stringify <EOL> ICMPV6_DST_UNREACH = <NUM_LIT:1> <EOL> ICMPV6_PACKET_TOO_BIG = <NUM_LIT:2> <EOL> ICMPV6_TIME_EXCEEDED = <NUM_LIT:3> <EOL> ICMPV6_PARAM_PROB = <NUM_LIT:4> <EOL> ICMPV6_ECHO_REQUEST = <NUM_LIT> <EOL> ICMPV6_ECHO_REPLY = <NUM_LIT> <EOL> MLD_LISTENER_QUERY = <NUM_LIT> <EOL> MLD_LISTENER_REPOR = <NUM_LIT> <EOL> MLD_LISTENER_DONE = <NUM_LIT> <EOL> MLDV2_LISTENER_REPORT = <NUM_LIT> <EOL> ICMPV6_MEMBERSHIP_QUERY = <NUM_LIT> <EOL> ICMPV6_MEMBERSHIP_REPORT = <NUM_LIT> <EOL> ICMPV6_MEMBERSHIP_REDUCTION = <NUM_LIT> <EOL> ND_ROUTER_SOLICIT = <NUM_LIT> <EOL> ND_ROUTER_ADVERT = <NUM_LIT> <EOL> ND_NEIGHBOR_SOLICIT = <NUM_LIT> <EOL> ND_NEIGHBOR_ADVERT = <NUM_LIT> <EOL> ND_REDIREC = <NUM_LIT> <EOL> ICMPV6_ROUTER_RENUMBERING = <NUM_LIT> <EOL> ICMPV6_WRUREQUEST = <NUM_LIT> <EOL> ICMPV6_WRUREPLY = <NUM_LIT> <EOL> ICMPV6_FQDN_QUERY = <NUM_LIT> <EOL> ICMPV6_FQDN_REPLY = <NUM_LIT> <EOL> ICMPV6_NI_QUERY = <NUM_LIT> <EOL> ICMPV6_NI_REPLY = <NUM_LIT> <EOL> ICMPV6_MAXTYPE = <NUM_LIT> <EOL> ND_OPTION_SLA = <NUM_LIT:1> <EOL> ND_OPTION_TLA = <NUM_LIT:2> <EOL> ND_OPTION_PI = <NUM_LIT:3> <EOL> ND_OPTION_RH = <NUM_LIT:4> <EOL> ND_OPTION_MTU = <NUM_LIT:5> <EOL> MODE_IS_INCLUDE = <NUM_LIT:1> <EOL> MODE_IS_EXCLUDE = <NUM_LIT:2> <EOL> CHANGE_TO_INCLUDE_MODE = <NUM_LIT:3> <EOL> CHANGE_TO_EXCLUDE_MODE = <NUM_LIT:4> <EOL> ALLOW_NEW_SOURCES = <NUM_LIT:5> <EOL> BLOCK_OLD_SOURCES = <NUM_LIT:6> <EOL> class icmpv6 ( packet_base . PacketBase ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _ICMPV6_TYPES = { } <EOL> @ staticmethod <EOL> def register_icmpv6_type ( * args ) : <EOL> def _register_icmpv6_type ( cls ) : <EOL> for type_ in args : <EOL> icmpv6 . _ICMPV6_TYPES [ type_ ] = cls <EOL> return cls <EOL> return _register_icmpv6_type <EOL> def __init__ ( self , type_ = <NUM_LIT:0> , code = <NUM_LIT:0> , csum = <NUM_LIT:0> , data = None ) : <EOL> super ( icmpv6 , self ) . __init__ ( ) <EOL> self . type_ = type_ <EOL> self . code = code <EOL> self . csum = csum <EOL> self . data = data <EOL> @ classmethod <EOL> def parser ( cls , buf ) : <EOL> ( type_ , code , csum ) = struct . unpack_from ( cls . _PACK_STR , buf ) <EOL> msg = cls ( type_ , code , csum ) <EOL> offset = cls . _MIN_LEN <EOL> if len ( buf ) > offset : <EOL> cls_ = cls . _ICMPV6_TYPES . get ( type_ , None ) <EOL> if cls_ : <EOL> msg . data = cls_ . parser ( buf , offset ) <EOL> else : <EOL> msg . data = buf [ offset : ] <EOL> return msg , None , None <EOL> def serialize ( self , payload , prev ) : <EOL> hdr = bytearray ( struct . pack ( icmpv6 . _PACK_STR , self . type_ , <EOL> self . code , self . csum ) ) <EOL> if self . data is not None : <EOL> if self . type_ in icmpv6 . _ICMPV6_TYPES : <EOL> hdr += self . data . serialize ( ) <EOL> else : <EOL> hdr += self . data <EOL> if self . csum == <NUM_LIT:0> : <EOL> self . csum = packet_utils . checksum_ip ( prev , len ( hdr ) , hdr + payload ) <EOL> struct . pack_into ( '<STR_LIT>' , hdr , <NUM_LIT:2> , self . csum ) <EOL> return hdr <EOL> def __len__ ( self ) : <EOL> length = self . _MIN_LEN <EOL> if self . data is not None : <EOL> length += len ( self . data ) <EOL> return length <EOL> @ icmpv6 . register_icmpv6_type ( ND_NEIGHBOR_SOLICIT , ND_NEIGHBOR_ADVERT ) <EOL> class nd_neighbor ( stringify . StringifyMixin ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _ND_OPTION_TYPES = { } <EOL> _TYPE = { <EOL> '<STR_LIT:ascii>' : [ <EOL> '<STR_LIT>' <EOL> ] <EOL> } <EOL> @ staticmethod <EOL> def register_nd_option_type ( * args ) : <EOL> def _register_nd_option_type ( cls ) : <EOL> nd_neighbor . _ND_OPTION_TYPES [ cls . option_type ( ) ] = cls <EOL> return cls <EOL> return _register_nd_option_type ( args [ <NUM_LIT:0> ] ) <EOL> def __init__ ( self , res = <NUM_LIT:0> , dst = '<STR_LIT>' , option = None ) : <EOL> self . res = res <EOL> self . dst = dst <EOL> self . option = option <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( res , dst ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> offset += cls . _MIN_LEN <EOL> option = None <EOL> if len ( buf ) > offset : <EOL> ( type_ , ) = struct . unpack_from ( '<STR_LIT>' , buf , offset ) <EOL> cls_ = cls . _ND_OPTION_TYPES . get ( type_ ) <EOL> if cls_ is not None : <EOL> option = cls_ . parser ( buf , offset ) <EOL> else : <EOL> option = buf [ offset : ] <EOL> msg = cls ( res >> <NUM_LIT> , addrconv . ipv6 . bin_to_text ( dst ) , option ) <EOL> return msg <EOL> def serialize ( self ) : <EOL> res = self . res << <NUM_LIT> <EOL> hdr = bytearray ( struct . pack ( <EOL> nd_neighbor . _PACK_STR , res , <EOL> addrconv . ipv6 . text_to_bin ( self . dst ) ) ) <EOL> if self . option is not None : <EOL> if isinstance ( self . option , nd_option ) : <EOL> hdr . extend ( self . option . serialize ( ) ) <EOL> else : <EOL> hdr . extend ( self . option ) <EOL> return six . binary_type ( hdr ) <EOL> def __len__ ( self ) : <EOL> length = self . _MIN_LEN <EOL> if self . option is not None : <EOL> length += len ( self . option ) <EOL> return length <EOL> @ icmpv6 . register_icmpv6_type ( ND_ROUTER_SOLICIT ) <EOL> class nd_router_solicit ( stringify . StringifyMixin ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _ND_OPTION_TYPES = { } <EOL> @ staticmethod <EOL> def register_nd_option_type ( * args ) : <EOL> def _register_nd_option_type ( cls ) : <EOL> nd_router_solicit . _ND_OPTION_TYPES [ cls . option_type ( ) ] = cls <EOL> return cls <EOL> return _register_nd_option_type ( args [ <NUM_LIT:0> ] ) <EOL> def __init__ ( self , res = <NUM_LIT:0> , option = None ) : <EOL> self . res = res <EOL> self . option = option <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( res , ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> offset += cls . _MIN_LEN <EOL> option = None <EOL> if len ( buf ) > offset : <EOL> ( type_ , ) = struct . unpack_from ( '<STR_LIT>' , buf , offset ) <EOL> cls_ = cls . _ND_OPTION_TYPES . get ( type_ ) <EOL> if cls_ is not None : <EOL> option = cls_ . parser ( buf , offset ) <EOL> else : <EOL> option = buf [ offset : ] <EOL> msg = cls ( res , option ) <EOL> return msg <EOL> def serialize ( self ) : <EOL> hdr = bytearray ( struct . pack ( <EOL> nd_router_solicit . _PACK_STR , self . res ) ) <EOL> if self . option is not None : <EOL> if isinstance ( self . option , nd_option ) : <EOL> hdr . extend ( self . option . serialize ( ) ) <EOL> else : <EOL> hdr . extend ( self . option ) <EOL> return six . binary_type ( hdr ) <EOL> def __len__ ( self ) : <EOL> length = self . _MIN_LEN <EOL> if self . option is not None : <EOL> length += len ( self . option ) <EOL> return length <EOL> @ icmpv6 . register_icmpv6_type ( ND_ROUTER_ADVERT ) <EOL> class nd_router_advert ( stringify . StringifyMixin ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _ND_OPTION_TYPES = { } <EOL> @ staticmethod <EOL> def register_nd_option_type ( * args ) : <EOL> def _register_nd_option_type ( cls ) : <EOL> nd_router_advert . _ND_OPTION_TYPES [ cls . option_type ( ) ] = cls <EOL> return cls <EOL> return _register_nd_option_type ( args [ <NUM_LIT:0> ] ) <EOL> def __init__ ( self , ch_l = <NUM_LIT:0> , res = <NUM_LIT:0> , rou_l = <NUM_LIT:0> , rea_t = <NUM_LIT:0> , ret_t = <NUM_LIT:0> , options = None ) : <EOL> self . ch_l = ch_l <EOL> self . res = res <EOL> self . rou_l = rou_l <EOL> self . rea_t = rea_t <EOL> self . ret_t = ret_t <EOL> options = options or [ ] <EOL> assert isinstance ( options , list ) <EOL> self . options = options <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( ch_l , res , rou_l , rea_t , ret_t <EOL> ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> offset += cls . _MIN_LEN <EOL> options = [ ] <EOL> while len ( buf ) > offset : <EOL> ( type_ , length ) = struct . unpack_from ( '<STR_LIT>' , buf , offset ) <EOL> cls_ = cls . _ND_OPTION_TYPES . get ( type_ ) <EOL> if cls_ is not None : <EOL> option = cls_ . parser ( buf , offset ) <EOL> else : <EOL> option = buf [ offset : offset + ( length * <NUM_LIT:8> - <NUM_LIT:2> ) ] <EOL> options . append ( option ) <EOL> offset += len ( option ) <EOL> msg = cls ( ch_l , res >> <NUM_LIT:6> , rou_l , rea_t , ret_t , options ) <EOL> return msg <EOL> def serialize ( self ) : <EOL> res = self . res << <NUM_LIT:6> <EOL> hdr = bytearray ( struct . pack ( <EOL> nd_router_advert . _PACK_STR , self . ch_l , res , self . rou_l , <EOL> self . rea_t , self . ret_t ) ) <EOL> for option in self . options : <EOL> if isinstance ( option , nd_option ) : <EOL> hdr . extend ( option . serialize ( ) ) <EOL> else : <EOL> hdr . extend ( option ) <EOL> return six . binary_type ( hdr ) <EOL> def __len__ ( self ) : <EOL> length = self . _MIN_LEN <EOL> for option in self . options : <EOL> length += len ( option ) <EOL> return length <EOL> @ six . add_metaclass ( abc . ABCMeta ) <EOL> class nd_option ( stringify . StringifyMixin ) : <EOL> @ classmethod <EOL> @ abc . abstractmethod <EOL> def option_type ( cls ) : <EOL> pass <EOL> @ abc . abstractmethod <EOL> def __init__ ( self , _type , length ) : <EOL> self . _type = _type <EOL> self . length = length <EOL> @ classmethod <EOL> @ abc . abstractmethod <EOL> def parser ( cls , buf ) : <EOL> pass <EOL> @ abc . abstractmethod <EOL> def serialize ( self ) : <EOL> pass <EOL> def __len__ ( self ) : <EOL> return self . _MIN_LEN <EOL> class nd_option_la ( nd_option ) : <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _TYPE = { <EOL> '<STR_LIT:ascii>' : [ <EOL> '<STR_LIT>' <EOL> ] <EOL> } <EOL> @ abc . abstractmethod <EOL> def __init__ ( self , length , hw_src , data ) : <EOL> super ( nd_option_la , self ) . __init__ ( self . option_type ( ) , length ) <EOL> self . hw_src = hw_src <EOL> self . data = data <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( _ , length , hw_src ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> msg = cls ( length , addrconv . mac . bin_to_text ( hw_src ) ) <EOL> offset += cls . _MIN_LEN <EOL> if len ( buf ) > offset : <EOL> msg . data = buf [ offset : ] <EOL> return msg <EOL> def serialize ( self ) : <EOL> buf = bytearray ( struct . pack ( <EOL> self . _PACK_STR , self . option_type ( ) , self . length , <EOL> addrconv . mac . text_to_bin ( self . hw_src ) ) ) <EOL> if self . data is not None : <EOL> buf . extend ( self . data ) <EOL> mod = len ( buf ) % <NUM_LIT:8> <EOL> if mod : <EOL> buf . extend ( bytearray ( <NUM_LIT:8> - mod ) ) <EOL> if <NUM_LIT:0> == self . length : <EOL> self . length = len ( buf ) // <NUM_LIT:8> <EOL> struct . pack_into ( '<STR_LIT>' , buf , <NUM_LIT:1> , self . length ) <EOL> return six . binary_type ( buf ) <EOL> def __len__ ( self ) : <EOL> length = self . _MIN_LEN <EOL> if self . data is not None : <EOL> length += len ( self . data ) <EOL> return length <EOL> @ nd_neighbor . register_nd_option_type <EOL> @ nd_router_solicit . register_nd_option_type <EOL> @ nd_router_advert . register_nd_option_type <EOL> class nd_option_sla ( nd_option_la ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def option_type ( cls ) : <EOL> return ND_OPTION_SLA <EOL> def __init__ ( self , length = <NUM_LIT:0> , hw_src = '<STR_LIT>' , data = None ) : <EOL> super ( nd_option_sla , self ) . __init__ ( length , hw_src , data ) <EOL> @ nd_neighbor . register_nd_option_type <EOL> class nd_option_tla ( nd_option_la ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def option_type ( cls ) : <EOL> return ND_OPTION_TLA <EOL> def __init__ ( self , length = <NUM_LIT:0> , hw_src = '<STR_LIT>' , data = None ) : <EOL> super ( nd_option_tla , self ) . __init__ ( length , hw_src , data ) <EOL> @ nd_router_advert . register_nd_option_type <EOL> class nd_option_pi ( nd_option ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _TYPE = { <EOL> '<STR_LIT:ascii>' : [ <EOL> '<STR_LIT>' <EOL> ] <EOL> } <EOL> @ classmethod <EOL> def option_type ( cls ) : <EOL> return ND_OPTION_PI <EOL> def __init__ ( self , length = <NUM_LIT:0> , pl = <NUM_LIT:0> , res1 = <NUM_LIT:0> , val_l = <NUM_LIT:0> , pre_l = <NUM_LIT:0> , res2 = <NUM_LIT:0> , <EOL> prefix = '<STR_LIT>' ) : <EOL> super ( nd_option_pi , self ) . __init__ ( self . option_type ( ) , length ) <EOL> self . pl = pl <EOL> self . res1 = res1 <EOL> self . val_l = val_l <EOL> self . pre_l = pre_l <EOL> self . res2 = res2 <EOL> self . prefix = prefix <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( _ , length , pl , res1 , val_l , pre_l , res2 , prefix <EOL> ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> msg = cls ( length , pl , res1 >> <NUM_LIT:5> , val_l , pre_l , res2 , <EOL> addrconv . ipv6 . bin_to_text ( prefix ) ) <EOL> return msg <EOL> def serialize ( self ) : <EOL> res1 = self . res1 << <NUM_LIT:5> <EOL> hdr = bytearray ( struct . pack ( <EOL> self . _PACK_STR , self . option_type ( ) , self . length , self . pl , <EOL> res1 , self . val_l , self . pre_l , self . res2 , <EOL> addrconv . ipv6 . text_to_bin ( self . prefix ) ) ) <EOL> if <NUM_LIT:0> == self . length : <EOL> self . length = len ( hdr ) // <NUM_LIT:8> <EOL> struct . pack_into ( '<STR_LIT>' , hdr , <NUM_LIT:1> , self . length ) <EOL> return six . binary_type ( hdr ) <EOL> @ icmpv6 . register_icmpv6_type ( ICMPV6_ECHO_REPLY , ICMPV6_ECHO_REQUEST ) <EOL> class echo ( stringify . StringifyMixin ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> def __init__ ( self , id_ = <NUM_LIT:0> , seq = <NUM_LIT:0> , data = None ) : <EOL> self . id = id_ <EOL> self . seq = seq <EOL> self . data = data <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( id_ , seq ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> msg = cls ( id_ , seq ) <EOL> offset += cls . _MIN_LEN <EOL> if len ( buf ) > offset : <EOL> msg . data = buf [ offset : ] <EOL> return msg <EOL> def serialize ( self ) : <EOL> hdr = bytearray ( struct . pack ( echo . _PACK_STR , self . id , <EOL> self . seq ) ) <EOL> if self . data is not None : <EOL> hdr += bytearray ( self . data ) <EOL> return hdr <EOL> def __len__ ( self ) : <EOL> length = self . _MIN_LEN <EOL> if self . data is not None : <EOL> length += len ( self . data ) <EOL> return length <EOL> @ icmpv6 . register_icmpv6_type ( <EOL> MLD_LISTENER_QUERY , MLD_LISTENER_REPOR , MLD_LISTENER_DONE ) <EOL> class mld ( stringify . StringifyMixin ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _TYPE = { <EOL> '<STR_LIT:ascii>' : [ <EOL> '<STR_LIT:address>' <EOL> ] <EOL> } <EOL> def __init__ ( self , maxresp = <NUM_LIT:0> , address = '<STR_LIT>' ) : <EOL> self . maxresp = maxresp <EOL> self . address = address <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> if cls . _MIN_LEN < len ( buf [ offset : ] ) : <EOL> msg = mldv2_query . parser ( buf [ offset : ] ) <EOL> else : <EOL> ( maxresp , address ) = struct . unpack_from ( <EOL> cls . _PACK_STR , buf , offset ) <EOL> msg = cls ( maxresp , addrconv . ipv6 . bin_to_text ( address ) ) <EOL> return msg <EOL> def serialize ( self ) : <EOL> buf = struct . pack ( mld . _PACK_STR , self . maxresp , <EOL> addrconv . ipv6 . text_to_bin ( self . address ) ) <EOL> return buf <EOL> def __len__ ( self ) : <EOL> return self . _MIN_LEN <EOL> class mldv2_query ( mld ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _TYPE = { <EOL> '<STR_LIT:ascii>' : [ <EOL> '<STR_LIT:address>' <EOL> ] , <EOL> '<STR_LIT>' : [ <EOL> '<STR_LIT>' <EOL> ] <EOL> } <EOL> def __init__ ( self , maxresp = <NUM_LIT:0> , address = '<STR_LIT>' , s_flg = <NUM_LIT:0> , qrv = <NUM_LIT:2> , <EOL> qqic = <NUM_LIT:0> , num = <NUM_LIT:0> , srcs = None ) : <EOL> super ( mldv2_query , self ) . __init__ ( maxresp , address ) <EOL> self . s_flg = s_flg <EOL> self . qrv = qrv <EOL> self . qqic = qqic <EOL> self . num = num <EOL> srcs = srcs or [ ] <EOL> assert isinstance ( srcs , list ) <EOL> for src in srcs : <EOL> assert isinstance ( src , str ) <EOL> self . srcs = srcs <EOL> @ classmethod <EOL> def parser ( cls , buf ) : <EOL> ( maxresp , address , s_qrv , qqic , num <EOL> ) = struct . unpack_from ( cls . _PACK_STR , buf ) <EOL> s_flg = ( s_qrv >> <NUM_LIT:3> ) & <NUM_LIT> <EOL> qrv = s_qrv & <NUM_LIT> <EOL> offset = cls . _MIN_LEN <EOL> srcs = [ ] <EOL> while <NUM_LIT:0> < len ( buf [ offset : ] ) and num > len ( srcs ) : <EOL> assert <NUM_LIT:16> <= len ( buf [ offset : ] ) <EOL> ( src , ) = struct . unpack_from ( '<STR_LIT>' , buf , offset ) <EOL> srcs . append ( addrconv . ipv6 . bin_to_text ( src ) ) <EOL> offset += <NUM_LIT:16> <EOL> assert num == len ( srcs ) <EOL> return cls ( maxresp , addrconv . ipv6 . bin_to_text ( address ) , s_flg , <EOL> qrv , qqic , num , srcs ) <EOL> def serialize ( self ) : <EOL> s_qrv = self . s_flg << <NUM_LIT:3> | self . qrv <EOL> buf = bytearray ( struct . pack ( self . _PACK_STR , self . maxresp , <EOL> addrconv . ipv6 . text_to_bin ( self . address ) , s_qrv , <EOL> self . qqic , self . num ) ) <EOL> for src in self . srcs : <EOL> buf . extend ( struct . pack ( '<STR_LIT>' , addrconv . ipv6 . text_to_bin ( src ) ) ) <EOL> if <NUM_LIT:0> == self . num : <EOL> self . num = len ( self . srcs ) <EOL> struct . pack_into ( '<STR_LIT>' , buf , <NUM_LIT> , self . num ) <EOL> return six . binary_type ( buf ) <EOL> def __len__ ( self ) : <EOL> return self . _MIN_LEN + len ( self . srcs ) * <NUM_LIT:16> <EOL> @ icmpv6 . register_icmpv6_type ( MLDV2_LISTENER_REPORT ) <EOL> class mldv2_report ( mld ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _class_prefixes = [ '<STR_LIT>' ] <EOL> def __init__ ( self , record_num = <NUM_LIT:0> , records = None ) : <EOL> self . record_num = record_num <EOL> records = records or [ ] <EOL> assert isinstance ( records , list ) <EOL> for record in records : <EOL> assert isinstance ( record , mldv2_report_group ) <EOL> self . records = records <EOL> @ classmethod <EOL> def parser ( cls , buf , offset ) : <EOL> ( record_num , ) = struct . unpack_from ( cls . _PACK_STR , buf , offset ) <EOL> offset += cls . _MIN_LEN <EOL> records = [ ] <EOL> while <NUM_LIT:0> < len ( buf [ offset : ] ) and record_num > len ( records ) : <EOL> record = mldv2_report_group . parser ( buf [ offset : ] ) <EOL> records . append ( record ) <EOL> offset += len ( record ) <EOL> assert record_num == len ( records ) <EOL> return cls ( record_num , records ) <EOL> def serialize ( self ) : <EOL> buf = bytearray ( struct . pack ( self . _PACK_STR , self . record_num ) ) <EOL> for record in self . records : <EOL> buf . extend ( record . serialize ( ) ) <EOL> if <NUM_LIT:0> == self . record_num : <EOL> self . record_num = len ( self . records ) <EOL> struct . pack_into ( '<STR_LIT>' , buf , <NUM_LIT:2> , self . record_num ) <EOL> return six . binary_type ( buf ) <EOL> def __len__ ( self ) : <EOL> records_len = <NUM_LIT:0> <EOL> for record in self . records : <EOL> records_len += len ( record ) <EOL> return self . _MIN_LEN + records_len <EOL> class mldv2_report_group ( stringify . StringifyMixin ) : <EOL> """<STR_LIT>""" <EOL> _PACK_STR = '<STR_LIT>' <EOL> _MIN_LEN = struct . calcsize ( _PACK_STR ) <EOL> _TYPE = { <EOL> '<STR_LIT:ascii>' : [ <EOL> '<STR_LIT:address>' <EOL> ] , <EOL> '<STR_LIT>' : [ <EOL> '<STR_LIT>' <EOL> ] <EOL> } <EOL> def __init__ ( self , type_ = <NUM_LIT:0> , aux_len = <NUM_LIT:0> , num = <NUM_LIT:0> , address = '<STR_LIT>' , <EOL> srcs = None , aux = None ) : <EOL> self . type_ = type_ <EOL> self . aux_len = aux_len <EOL> self . num = num <EOL> self . address = address <EOL> srcs = srcs or [ ] <EOL> assert isinstance ( srcs , list ) <EOL> for src in srcs : <EOL> assert isinstance ( src , str ) <EOL> self . srcs = srcs <EOL> self . aux = aux <EOL> @ classmethod <EOL> def parser ( cls , buf ) : <EOL> ( type_ , aux_len , num , address <EOL> ) = struct . unpack_from ( cls . _PACK_STR , buf ) <EOL> offset = cls . _MIN_LEN <EOL> srcs = [ ] <EOL> while <NUM_LIT:0> < len ( buf [ offset : ] ) and num > len ( srcs ) : <EOL> assert <NUM_LIT:16> <= len ( buf [ offset : ] ) <EOL> ( src , ) = struct . unpack_from ( '<STR_LIT>' , buf , offset ) <EOL> srcs . append ( addrconv . ipv6 . bin_to_text ( src ) ) <EOL> offset += <NUM_LIT:16> <EOL> assert num == len ( srcs ) <EOL> aux = None <EOL> if aux_len : <EOL> ( aux , ) = struct . unpack_from ( '<STR_LIT>' % ( aux_len * <NUM_LIT:4> ) , buf , offset ) <EOL> msg = cls ( type_ , aux_len , num , addrconv . ipv6 . bin_to_text ( address ) , <EOL> srcs , aux ) <EOL> return msg <EOL> def serialize ( self ) : <EOL> buf = bytearray ( struct . pack ( self . _PACK_STR , self . type_ , <EOL> self . aux_len , self . num , <EOL> addrconv . ipv6 . text_to_bin ( self . address ) ) ) <EOL> for src in self . srcs : <EOL> buf . extend ( struct . pack ( '<STR_LIT>' , addrconv . ipv6 . text_to_bin ( src ) ) ) <EOL> if <NUM_LIT:0> == self . num : <EOL> self . num = len ( self . srcs ) <EOL> struct . pack_into ( '<STR_LIT>' , buf , <NUM_LIT:2> , self . num ) <EOL> if self . aux is not None : <EOL> mod = len ( self . aux ) % <NUM_LIT:4> <EOL> if mod : <EOL> self . aux += bytearray ( <NUM_LIT:4> - mod ) <EOL> self . aux = six . binary_type ( self . aux ) <EOL> buf . extend ( self . aux ) <EOL> if <NUM_LIT:0> == self . aux_len : <EOL> self . aux_len = len ( self . aux ) // <NUM_LIT:4> <EOL> struct . pack_into ( '<STR_LIT>' , buf , <NUM_LIT:1> , self . aux_len ) <EOL> return six . binary_type ( buf ) <EOL> def __len__ ( self ) : <EOL> return self . _MIN_LEN + len ( self . srcs ) * <NUM_LIT:16> + self . aux_len * <NUM_LIT:4> <EOL> icmpv6 . set_classes ( icmpv6 . _ICMPV6_TYPES ) <EOL> nd_neighbor . set_classes ( nd_neighbor . _ND_OPTION_TYPES ) <EOL> nd_router_solicit . set_classes ( nd_router_solicit . _ND_OPTION_TYPES ) <EOL> nd_router_advert . set_classes ( nd_router_advert . _ND_OPTION_TYPES ) </s>
