
    |;iaA                       U d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z# dZ$dZ%dZ&dZ'e(ejR                  efZ*i Z+de,d<   e-Z.e/Z0 G d d      Z1y)a  Multicast DNS Service Discovery for Python, v0.14-wmcbrine
Copyright 2003 Paul Scott-Murphy, 2014 William McBrine

This module provides a framework for the use of DNS Service Discovery
using IP multicast.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
    )annotationsN)Any   )
DNSAddressDNSHinfoDNSNsec
DNSPointerDNSQuestion	DNSRecord
DNSServiceDNSText)IncomingDecodeError)log)current_time_millis)_FLAGS_QR_MASK_FLAGS_QR_QUERY_FLAGS_QR_RESPONSE	_FLAGS_TC_TYPE_A
_TYPE_AAAA_TYPE_CNAME_TYPE_HINFO
_TYPE_NSEC	_TYPE_PTR	_TYPE_SRV	_TYPE_TXT_TYPES         zdict[str, int | tuple]
_seen_logsc                  L   e Zd ZdZdZ	 	 	 d	 	 	 	 	 	 	 	 	 ddZddZddZddZe	dd       Z
e	dd	       Ze	d d
       Ze	d d       Ze	d d       Ze	d d       Zd!dZed"d       Zd#dZddZd$dZd!dZd!dZd$dZd%dZd!dZ	 	 	 	 	 	 	 	 	 	 	 	 d&dZd'dZd$dZd(dZy))DNSIncomingz/Object representation of an incoming DNS packet)_answers	_data_len_did_read_others_has_qu_question_name_cache_num_additionals_num_answers_num_authorities_num_questions
_questionsdataflagsidnowoffsetscope_idsourcevalidviewNc                   d| _         d| _        || _        || _        t	        |      | _        i | _        g | _        g | _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        |xs
 t!               | _        || _        || _        d| _        	 | j+                          y# t,        $ r5 | j/                  d| j$                  | j                  | j                         Y yw xY w)z/Constructor from string holding bytes of packetr   F?Received invalid packet from %s at offset %d while unpacking %rN)r/   r2   r.   r6   lenr%   r(   r-   r$   r0   r,   r*   r+   r)   r5   r&   r   r1   r4   r3   r'   _initial_parseDECODE_EXCEPTIONS_log_exception_debug)selfr.   r4   r3   r1   s        N/home/ubuntu/myenv/lib/python3.12/site-packages/zeroconf/_protocol/incoming.py__init__zDNSIncoming.__init__`   s     
		T13-/)+ ! !
 %/-/  %	!  	%%Q				s   B- -;C+*C+c                6    | j                   t        z  t        k(  S )z Returns true if this is a query.)r/   r   r   r=   s    r>   is_queryzDNSIncoming.is_query   s    

^+??    c                6    | j                   t        z  t        k(  S )z#Returns true if this is a response.)r/   r   r   rA   s    r>   is_responsezDNSIncoming.is_response   s    

^+0BBBrC   c                    | j                   S )z.Returns true if any question is a QU question.)r'   rA   s    r>   has_qu_questionzDNSIncoming.has_qu_question   s    $$$rC   c                6    | j                   t        z  t        k(  S )z$Returns true if this is a truncated.)r/   r   rA   s    r>   	truncatedzDNSIncoming.truncated   s     

Y&944rC   c                    | j                   S )zQuestions in the packet.)r-   rA   s    r>   	questionszDNSIncoming.questions   s     rC   c                    | j                   S )z"Number of questions in the packet.)r,   rA   s    r>   num_questionszDNSIncoming.num_questions   s     """rC   c                    | j                   S )z Number of answers in the packet.)r*   rA   s    r>   num_answerszDNSIncoming.num_answers   s        rC   c                    | j                   S )z$Number of authorities in the packet.r+   rA   s    r>   num_authoritieszDNSIncoming.num_authorities        $$$rC   c                    | j                   S )z$Number of additionals in the packet.)r)   rA   s    r>   num_additionalszDNSIncoming.num_additionals   rS   rC   c                    | j                          | j                          | j                  s| j                          d| _        y)z6Parse the data needed to initialize the packet object.TN)_read_header_read_questionsr,   _read_othersr5   rA   s    r>   r:   zDNSIncoming._initial_parse   s6    ""
rC   c                    d}t        j                         }t        |d         }|t        vr|t        |<   d}t	        j
                  |xs dgd|i y )NFr   TzException occurredexc_info)sysr[   strr!   r   debug)clslogger_datalog_exc_infor[   exc_strs        r>   r<   z DNSIncoming._log_exception_debug   sQ    <<>hqk"*$"*JwL		K9$8#9R\RrC   c                   | j                   s	 | j                          | j                  S | j                  S # t        $ r@ | j                  d| j                  | j
                  | j                         Y | j                  S w xY w)zAnswers in the packet.r8   )r&   rY   r;   r<   r4   r2   r.   r$   rA   s    r>   answerszDNSIncoming.answers   st    $$!!# }}t}} % ))UKKKKII	 }}s   6 ;A?>A?c                     | j                   dkD  S )z Returns true if this is a probe.r   rQ   rA   s    r>   is_probezDNSIncoming.is_probe   s    $$q((rC   c                F   dj                  dj                  d| j                   d| j                   d| j                   d| j
                   d| j                   d| j                   d	| j                   d
| j                   d| j                          g	            S )Nz<DNSIncoming:{}>z, zid=zflags=z
truncated=zn_q=zn_ans=zn_auth=zn_add=z
questions=zanswers=)formatjoinr0   r/   rI   r,   r*   r+   r)   r-   rd   rA   s    r>   __repr__zDNSIncoming.__repr__   s    !((II$''OTZZL)  014../0T../0d3345T2234  12t||~./

 	
rC   c                   | j                   }| j                  }| xj                  dz  c_        ||   dz  ||dz      z  | _        ||dz      dz  ||dz      z  | _        ||dz      dz  ||dz      z  | _        ||dz      dz  ||d	z      z  | _        ||dz      dz  ||d
z      z  | _        ||dz      dz  ||dz      z  | _        y)zReads header portion of packet      r   r                  	   
      N)r6   r2   r0   r/   r,   r*   r+   r)   )r=   r6   r2   s      r>   rW   zDNSIncoming._read_header   s    yyrv,!#d6A:&66&1*%*T&1*-==
"6A:.!3d6A:6FF !,1D!4DD $VaZ 0A 5VaZ8H H $Vb[ 1Q 6frk9J JrC   c                   | j                   }| j                  }t        | j                        D ]  }| j	                         }| j
                  }| xj
                  dz  c_        ||   dz  ||dz      z  }||dz      dz  ||dz      z  }t        j                  t              }|j                  |||       |j                  rd| _
        |j                  |        y)z!Reads questions section of packetro   rm   r   r   rn   TN)r6   r-   ranger,   
_read_namer2   r
   __new__
_fast_inituniquer'   append)	r=   r6   rK   _namer2   type_class_questions	            r>   rX   zDNSIncoming._read_questions   s    yyOO	t**+ 	'A??$D[[FKK1KLA%VaZ(88E&1*%*T&1*-==F"**;7HeV4(,%X&	'rC   c                    | j                   | j                     }| xj                  dz  c_        | j                  | j                  | j                  |z    j                  dd      }| xj                  |z  c_        |S )z(Reads a character string from the packetr   utf-8replace)r6   r2   r.   decoder=   lengthinfos      r>   _read_character_stringz"DNSIncoming._read_character_string  s_    4;;'qyyt{{V';<CCGYWvrC   c                |    | j                   | j                  | j                  |z    }| xj                  |z  c_        |S )z0Reads a string of a given length from the packet)r.   r2   r   s      r>   _read_stringzDNSIncoming._read_string  s2    yyt{{V';<vrC   c           
        d| _         | j                  }| j                  | j                  z   | j                  z   }t        |      D ]  }| j                         }| j                  }| xj                  dz  c_        ||   dz  ||dz      z  }||dz      dz  ||dz      z  }||dz      dz  ||d	z      d
z  z  ||dz      dz  z  ||dz      z  }||dz      dz  ||dz      z  }	| j                  |	z   }
d}	 | j                  |||||	      }|| j                  j!                  |        y# t        $ rM |
| _        t        j                  d|t        j                  ||      | j                  | j                  d       Y vw xY w)zLReads the answers, authorities and additionals section of the
        packetTrt   rm   r   r   rn   ro      rp      rq   rr   rs   NzTUnable to parse; skipping record for %s with type %s at offset %d while unpacking %r)r[   )r&   r6   r*   r+   r)   rw   rx   r2   _read_recordr;   r   r^   r   getr.   r$   r|   )r=   r6   nr}   domainr2   r   r   ttlr   endrecs               r>   rY   zDNSIncoming._read_others  s    !%yy 5 558M8MMq 	*A__&F[[FKK2K LA%VaZ(88E&1*%*T&1*-==Fvz"b(4
+;r+AADRSDTXYDYY\`agjkak\llC&1*%*T&1*-==F++&CC''vsFK $$S)9	* %  "		jJJue,KKII!s   0D&&AE<;E<c                    |t         k(  rKt        j                  t              }|j                  ||||| j	                  d      d| j
                         |S |t        t        fv rIt        j                  t              }|j                  ||||| j                         | j
                         |S |t        k(  rJt        j                  t              }|j                  ||||| j	                  |      | j
                         |S |t        k(  r| j                  }	| j                  }
| xj                  dz  c_        |	|
   dz  |	|
dz      z  }|	|
dz      dz  |	|
dz      z  }|	|
dz      dz  |	|
dz      z  }t        j                  t              }|j                  |||||||| j                         | j
                  	       |S |t         k(  rXt#        j                  t"              }|j                  ||||| j%                         | j%                         | j
                         |S |t&        k(  rUt        j                  t              }|j                  ||||| j	                  d	      | j(                  | j
                         |S |t*        k(  rh| j                  }t-        j                  t,              }|j                  ||||| j                         | j/                  ||z         | j
                         |S | xj                  |z  c_        y)
z/Read known records types and skip unknown ones.ro   Nrq   rm   r   r   rn   rp   r   )r   r   ry   rz   r   r1   r   r   r	   rx   r   r   r   r6   r2   r   r   r   r   r   r3   r   r   _read_bitmap)r=   r   r   r   r   r   address_recpointer_rectext_recr6   r2   priorityweightportsrv_rec	hinfo_rec
name_startnsec_recs                     r>   r   zDNSIncoming._read_record5  s    G$,,Z8K""65&#t?P?PQR?SUY[_[c[cd[),,$,,Z8K""65&#t?PRVRZRZ[Iw/HvsD<M<Mf<UW[W_W_`OI99D[[FKK1KF|q(4
+;;H&1*%*T&1*-==F
#q(4
+;;D ((4G!
 NK ((2I  ++-++- J$,,Z8K""!!"% JJw/H!!!*v"56 O 	vrC   c                   g }| j                   }| j                  |k  r| j                  }|dz   }|dz   }||   }||   }||z   }	t        | j                  ||	       D ];  \  }
}t	        d      D ](  }|d|z	  z  s|j                  ||dz  z   |
dz  z          * = | xj                  d|z   z  c_        | j                  |k  r|S )z%Reads an NSEC bitmap from the packet.r   r   rm   r      )r6   r2   	enumerater.   rw   r|   )r=   r   rdtypesr6   r2   offset_plus_oneoffset_plus_twowindowbitmap_length
bitmap_endibytebits                r>   r   zDNSIncoming._read_bitmap  s    yykkC[[F$qjO$qjO&\F 1M(=8J$TYYz%JK C4 8 CCts{+sVc\'9AE'ABCC KK1},,K kkC rC   c                   g }t               }| j                  }| j                  |||      | _        || j                  |<   dj	                  |      dz   }t        |      t        kD  r"t        d| dt         d| j                         |S )z$Reads a domain name from the packet..z	DNS name z exceeds maximum length of  from )	setr2   _decode_labels_at_offsetr(   ri   r9   MAX_NAME_LENGTHr   r4   )r=   labelsseen_pointersoriginal_offsetr~   s        r>   rx   zDNSIncoming._read_name  s    "%%++33OV][,2)xx#%t9&%D6!<_<MVTXT_T_S`a  rC   c                   | j                   }|| j                  k  r||   }|dk(  r	|t        z   S |dk  rG|t        z   }|j                  | j                  |||z    j                  dd             |t        |z   z  }o|dk  rt        d| d| d| j                         ||d	z      }|d
z  dz  |z   }|}	|| j                  kD  rt        d| d| d| j                         ||k(  rt        d| d| j                         |	|v rt        d| d| j                         | j                  j                  |	      }
|
s5g }
|j                  |	       | j                  ||
|       |
| j                  |	<   |j                  |
       t        |      t        kD  rt        d| d| j                         |t        z   S t        d| j                         )Nr   @   r   r      zDNS compression type z is unknown at r   r   ?   r   zDNS compression pointer at z points to z beyond packet from z points to itself from z was seen again from z7Maximum dns labels reached while processing pointer at z1Corrupt packet received while decoding name from )r6   r%   DNS_COMPRESSION_HEADER_LENr|   r.   r   r   r4   r(   r   addr   extendr9   MAX_DNS_LABELSDNS_COMPRESSION_POINTER_LEN)r=   offr   r   r6   r   	label_idx	link_datalinklink_py_intlinked_labelss              r>   r   z$DNSIncoming._decode_labels_at_offset  s   yyDNN"#YF{777}"<<	dii	I4FGNNwXabc1F::})+F8?3%vdkk][ 
 S1WITMS(94DKdnn$)1#k$G[\`\g\g[hi  s{)1#6Mdkk][  m+)1#6KDKK=Y  !,,00=M  "!!+.--dM=Q0=  -MM-(6{^+)McURXY]YdYdXef  444!$UVZVaVaUb"cddrC   )NNN)
r.   bytesr4   ztuple[str, int] | Noner3   z
int | Noner1   zfloat | NonereturnNone)r   bool)r   zlist[DNSQuestion])r   int)r   r   )r`   r   r   r   )r   zlist[DNSRecord])r   r]   )r   _intr   r   )r   _strr   r   r   r   r   r   r   r   r   zDNSRecord | None)r   r   r   z	list[int])r   r   r   z	list[str]r   zset[int]r   r   )__name__
__module____qualname____doc__	__slots__r?   rB   rE   rG   propertyrI   rK   rM   rO   rR   rU   r:   classmethodr<   rd   rf   rj   rW   rX   r   r   rY   r   r   rx   r    rC   r>   r#   r#   G   sh   9I2 *.# ## '# 	#
 # 
#J@C% 5 5   # # ! ! % % % % S S)
"K'""*HNN#'N15N<@NJNN	N`$0erC   r#   )2r   
__future__r   structr\   typingr   _dnsr   r   r   r	   r
   r   r   r   _exceptionsr   _loggerr   _utils.timer   constr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   
IndexErrorerrorr;   r!   __annotations__r]   r   r   r   r#   r   rC   r>   <module>r      s   , #  
 	 	 	 .  -       /BC  &(
" '

Ne NerC   