@@ -390,6 +390,71 @@ int dns_encode_a_response(char *buf, size_t buflen, struct query *q)
390390 return len ;
391391}
392392
393+ int dns_encode_nxdomain (char * buf , size_t buflen , struct query * q , const char * zone )
394+ {
395+ char rnamebuf [256 ];
396+ char nsbuf [256 ];
397+ HEADER * header ;
398+ char * soa_start ;
399+ char * p ;
400+
401+ if (buflen < sizeof (HEADER ))
402+ return 0 ;
403+
404+ memset (buf , 0 , buflen );
405+ header = (HEADER * )buf ;
406+
407+ header -> id = htons (q -> id );
408+ header -> qr = 1 ; // response
409+ header -> opcode = 0 ;
410+ header -> aa = 1 ; // authoritative
411+ header -> tc = 0 ;
412+ header -> rd = 0 ;
413+ header -> ra = 0 ;
414+ header -> rcode = 3 ; // NXDOMAIN
415+
416+ header -> qdcount = htons (1 );
417+ header -> ancount = htons (0 );
418+ header -> nscount = htons (1 ); // We'll include SOA
419+ header -> arcount = htons (0 );
420+
421+ p = buf + sizeof (HEADER );
422+
423+ // Question section
424+ putname (& p , buflen - (p - buf ), q -> name );
425+ CHECKLEN (4 );
426+ putshort (& p , q -> type );
427+ putshort (& p , C_IN );
428+
429+ // Authority section (SOA)
430+ CHECKLEN (10 );
431+ putname (& p , buflen - (p - buf ), zone ); // zone name (owner of SOA)
432+ putshort (& p , T_SOA );
433+ putshort (& p , C_IN );
434+ putlong (& p , 60 ); // TTL
435+
436+ soa_start = p ;
437+ p += 2 ; // skip rdlength (to be filled later)
438+
439+ // Primary NS and responsible mailbox
440+ snprintf (nsbuf , sizeof (nsbuf ), "ns.%s" , zone );
441+ putname (& p , buflen - (p - buf ), nsbuf );
442+ snprintf (rnamebuf , sizeof (rnamebuf ), "hostmaster.%s" , zone );
443+ putname (& p , buflen - (p - buf ), rnamebuf );
444+
445+ // SOA fields: serial, refresh, retry, expire, minimum
446+ putlong (& p , 1 ); // serial
447+ putlong (& p , 3600 ); // refresh
448+ putlong (& p , 1800 ); // retry
449+ putlong (& p , 604800 ); // expire
450+ putlong (& p , 60 ); // minimum
451+
452+ int soalen = p - soa_start - 2 ;
453+ putshort (& soa_start , soalen ); // fill in rdlength
454+
455+ return p - buf ;
456+ }
457+
393458#undef CHECKLEN
394459
395460unsigned short dns_get_id (char * packet , size_t packetlen )
0 commit comments