From: Matthew Iselin <matt...@theiselins.net> Signed-off-by: Matthew Iselin <matt...@theiselins.net> --- src/include/gpxe/dns.h | 7 +++++++ src/net/udp/dns.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/src/include/gpxe/dns.h b/src/include/gpxe/dns.h index 9e5e874..49eb7a3 100644 --- a/src/include/gpxe/dns.h +++ b/src/include/gpxe/dns.h @@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define DNS_TYPE_A 1 #define DNS_TYPE_CNAME 5 +#define DNS_TYPE_AAAA 28 #define DNS_TYPE_ANY 255 #define DNS_CLASS_IN 1 @@ -78,6 +79,11 @@ struct dns_rr_info_a { struct in_addr in_addr; } __attribute__ (( packed )); +struct dns_rr_info_aaaa { + struct dns_rr_info_common common; + struct in6_addr in6_addr; +} __attribute__ (( packed )); + struct dns_rr_info_cname { struct dns_rr_info_common common; char cname[0]; @@ -86,6 +92,7 @@ struct dns_rr_info_cname { union dns_rr_info { struct dns_rr_info_common common; struct dns_rr_info_a a; + struct dns_rr_info_aaaa aaaa; struct dns_rr_info_cname cname; }; diff --git a/src/net/udp/dns.c b/src/net/udp/dns.c index c7bb6aa..cf513bf 100644 --- a/src/net/udp/dns.c +++ b/src/net/udp/dns.c @@ -334,6 +334,7 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, const struct dns_header *reply = data; union dns_rr_info *rr_info; struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; unsigned int qtype = dns->qinfo->qtype; /* Sanity check */ @@ -400,6 +401,19 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, } break; + case htons ( DNS_TYPE_AAAA ): + + /* Found the target AAAA record */ + DBGC ( dns, "DNS %p found address %s\n", + dns, inet6_ntoa ( rr_info->aaaa.in6_addr ) ); + sin6 = ( struct sockaddr_in6 * ) &dns->sa; + sin6->sin_family = AF_INET6; + sin6->sin6_addr = rr_info->aaaa.in6_addr; + + /* Mark operation as complete */ + dns_done ( dns, 0 ); + return 0; + default: DBGC ( dns, "DNS %p got unknown record type %d\n", dns, ntohs ( rr_info->common.type ) ); @@ -414,19 +428,28 @@ static int dns_xfer_deliver_raw ( struct xfer_interface *socket, case htons ( DNS_TYPE_A ): /* We asked for an A record and got nothing; + * try the AAAA record. + */ + DBGC ( dns, "DNS %p found no A record; trying AAAA\n", dns ); + dns->qinfo->qtype = htons ( DNS_TYPE_AAAA ); + dns_send_packet ( dns ); + return 0; + + case htons ( DNS_TYPE_AAAA ): + /* We asked for an AAAA record and got nothing; * try the CNAME. */ - DBGC ( dns, "DNS %p found no A record; trying CNAME\n", dns ); + DBGC ( dns, "DNS %p found no AAAA record; trying CNAME\n", dns ); dns->qinfo->qtype = htons ( DNS_TYPE_CNAME ); dns_send_packet ( dns ); return 0; case htons ( DNS_TYPE_CNAME ): /* We asked for a CNAME record. If we got a response - * (i.e. if the next A query is already set up), then + * (i.e. if the next AAAA query is already set up), then * issue it, otherwise abort. */ - if ( dns->qinfo->qtype == htons ( DNS_TYPE_A ) ) { + if ( dns->qinfo->qtype == htons ( DNS_TYPE_AAAA ) ) { dns_send_packet ( dns ); return 0; } else { -- 1.7.2.5 _______________________________________________ gPXE-devel mailing list gPXE-devel@etherboot.org http://etherboot.org/mailman/listinfo/gpxe-devel