4040
4141static bool llmnr_ipv6 = false;
4242/* Host name in DNS name format (length octet + name + 0 byte) */
43- static char llmnr_hostname [LLMNR_LABEL_MAX_SIZE + 2 ];
43+ #define LLMNR_LABEL_LEN (LLMNR_LABEL_MAX_SIZE + 2)
44+ static char * * llmnr_hostnames = NULL ;
45+ int llmnr_hostname_count = 0 ;
46+
47+ static void set_hostname (int entry_index , const char * hostname )
48+ {
49+ char * entry_llmnr_hostname = NULL ;
50+
51+ llmnr_hostnames [entry_index ] = xzalloc (LLMNR_LABEL_LEN );
52+ entry_llmnr_hostname = llmnr_hostnames [entry_index ];
53+
54+ entry_llmnr_hostname [0 ] = strlen (hostname );
55+ strncpy (& entry_llmnr_hostname [1 ], hostname , LLMNR_LABEL_MAX_SIZE );
56+ entry_llmnr_hostname [LLMNR_LABEL_MAX_SIZE + 1 ] = '\0' ;
57+ }
4458
4559void llmnr_set_hostname (const char * hostname )
4660{
47- llmnr_hostname [0 ] = strlen (hostname );
48- strncpy (& llmnr_hostname [1 ], hostname , LLMNR_LABEL_MAX_SIZE );
49- llmnr_hostname [LLMNR_LABEL_MAX_SIZE + 1 ] = '\0' ;
61+ set_hostname (0 , hostname );
5062}
5163
52- void llmnr_init (const char * hostname , bool ipv6 )
64+ void llmnr_init (const char * hostnames [], int hostname_count , bool ipv6 )
5365{
54- llmnr_set_hostname (hostname );
66+ int name_i = 0 ;
67+ llmnr_hostname_count = hostname_count ;
68+ llmnr_hostnames = xzalloc (hostname_count );
69+ for (;name_i < hostname_count ; ++ name_i ) {
70+ set_hostname (name_i , hostnames [name_i ]);
71+ }
5572 llmnr_ipv6 = ipv6 ;
5673}
5774
58- static bool llmnr_name_matches (const uint8_t * query )
75+ void llmnr_release () {
76+ int name_i = 0 ;
77+ for (; name_i < llmnr_hostname_count ; ++ name_i ) {
78+ free (llmnr_hostnames [name_i ]);
79+ }
80+ free (llmnr_hostnames );
81+ }
82+
83+ /* Return the matched name entry (first byte represents the string length) or NULL */
84+ static char * llmnr_name_matches (const uint8_t * query )
5985{
60- uint8_t n = llmnr_hostname [0 ];
86+ uint8_t n ;
87+ int name_i = 0 ;
88+
89+ for (; name_i < llmnr_hostname_count ; ++ name_i ) {
90+ n = llmnr_hostnames [name_i ][0 ];
91+
92+ /* length */
93+ if (query [0 ] != n )
94+ continue ;
95+ /* NULL byte */
96+ if (query [1 + n ] != 0 )
97+ continue ;
98+
99+ if (strncasecmp ((const char * )& query [1 ], & llmnr_hostnames [name_i ][1 ], n ) == 0 )
100+ return llmnr_hostnames [name_i ];
101+ }
61102
62- /* length */
63- if (query [0 ] != n )
64- return false;
65- /* NULL byte */
66- if (query [1 + n ] != 0 )
67- return false;
68103
69- return strncasecmp (( const char * ) & query [ 1 ], & llmnr_hostname [ 1 ], n ) == 0 ;
104+ return NULL ;
70105}
71106
72107static void llmnr_respond (unsigned int ifindex , const struct llmnr_hdr * hdr ,
73108 const uint8_t * query , size_t query_len , int sock ,
74- const struct sockaddr_storage * sst )
109+ const struct sockaddr_storage * sst , char * matched_hostname_entry )
75110{
76111 uint16_t qtype , qclass ;
77112 uint8_t name_len = query [0 ];
@@ -164,7 +199,7 @@ static void llmnr_respond(unsigned int ifindex, const struct llmnr_hdr *hdr,
164199
165200 /* NAME */
166201 if (i == 0 )
167- memcpy (pkt_put (p , llmnr_hostname [0 ] + 2 ), llmnr_hostname , llmnr_hostname [0 ] + 2 );
202+ memcpy (pkt_put (p , matched_hostname_entry [0 ] + 2 ), matched_hostname_entry , matched_hostname_entry [0 ] + 2 );
168203 else {
169204 /* message compression (RFC 1035, section 4.1.3) */
170205 uint16_t ptr = 0xC000 | (sizeof (* hdr ) + query_len );
@@ -196,6 +231,7 @@ static void llmnr_packet_process(int ifindex, const uint8_t *pktbuf, size_t len,
196231 const uint8_t * query ;
197232 size_t query_len ;
198233 uint8_t name_len ;
234+ char * matched_hostname_entry ;
199235
200236 /* Query too short? */
201237 if (len < sizeof (struct llmnr_hdr ))
@@ -218,8 +254,9 @@ static void llmnr_packet_process(int ifindex, const uint8_t *pktbuf, size_t len,
218254 return ;
219255
220256 /* Authoritative? */
221- if (llmnr_name_matches (query ))
222- llmnr_respond (ifindex , hdr , query , query_len , sock , sst );
257+ matched_hostname_entry = llmnr_name_matches (query );
258+ if (matched_hostname_entry )
259+ llmnr_respond (ifindex , hdr , query , query_len , sock , sst , matched_hostname_entry );
223260}
224261
225262void llmnr_recv (int sock )
0 commit comments