...

Source file src/github.com/miekg/dns/format.go

Documentation: github.com/miekg/dns

     1  package dns
     2  
     3  import (
     4  	"net"
     5  	"reflect"
     6  	"strconv"
     7  )
     8  
     9  // NumField returns the number of rdata fields r has.
    10  func NumField(r RR) int {
    11  	return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header
    12  }
    13  
    14  // Field returns the rdata field i as a string. Fields are indexed starting from 1.
    15  // RR types that holds slice data, for instance the NSEC type bitmap will return a single
    16  // string where the types are concatenated using a space.
    17  // Accessing non existing fields will cause a panic.
    18  func Field(r RR, i int) string {
    19  	if i == 0 {
    20  		return ""
    21  	}
    22  	d := reflect.ValueOf(r).Elem().Field(i)
    23  	switch d.Kind() {
    24  	case reflect.String:
    25  		return d.String()
    26  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    27  		return strconv.FormatInt(d.Int(), 10)
    28  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    29  		return strconv.FormatUint(d.Uint(), 10)
    30  	case reflect.Slice:
    31  		switch reflect.ValueOf(r).Elem().Type().Field(i).Tag {
    32  		case `dns:"a"`:
    33  			// TODO(miek): Hmm store this as 16 bytes
    34  			if d.Len() < net.IPv4len {
    35  				return ""
    36  			}
    37  			if d.Len() < net.IPv6len {
    38  				return net.IPv4(byte(d.Index(0).Uint()),
    39  					byte(d.Index(1).Uint()),
    40  					byte(d.Index(2).Uint()),
    41  					byte(d.Index(3).Uint())).String()
    42  			}
    43  			return net.IPv4(byte(d.Index(12).Uint()),
    44  				byte(d.Index(13).Uint()),
    45  				byte(d.Index(14).Uint()),
    46  				byte(d.Index(15).Uint())).String()
    47  		case `dns:"aaaa"`:
    48  			if d.Len() < net.IPv6len {
    49  				return ""
    50  			}
    51  			return net.IP{
    52  				byte(d.Index(0).Uint()),
    53  				byte(d.Index(1).Uint()),
    54  				byte(d.Index(2).Uint()),
    55  				byte(d.Index(3).Uint()),
    56  				byte(d.Index(4).Uint()),
    57  				byte(d.Index(5).Uint()),
    58  				byte(d.Index(6).Uint()),
    59  				byte(d.Index(7).Uint()),
    60  				byte(d.Index(8).Uint()),
    61  				byte(d.Index(9).Uint()),
    62  				byte(d.Index(10).Uint()),
    63  				byte(d.Index(11).Uint()),
    64  				byte(d.Index(12).Uint()),
    65  				byte(d.Index(13).Uint()),
    66  				byte(d.Index(14).Uint()),
    67  				byte(d.Index(15).Uint()),
    68  			}.String()
    69  		case `dns:"nsec"`:
    70  			if d.Len() == 0 {
    71  				return ""
    72  			}
    73  			s := Type(d.Index(0).Uint()).String()
    74  			for i := 1; i < d.Len(); i++ {
    75  				s += " " + Type(d.Index(i).Uint()).String()
    76  			}
    77  			return s
    78  		default:
    79  			// if it does not have a tag its a string slice
    80  			fallthrough
    81  		case `dns:"txt"`:
    82  			if d.Len() == 0 {
    83  				return ""
    84  			}
    85  			s := d.Index(0).String()
    86  			for i := 1; i < d.Len(); i++ {
    87  				s += " " + d.Index(i).String()
    88  			}
    89  			return s
    90  		}
    91  	}
    92  	return ""
    93  }
    94  

View as plain text