gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

format.go (2454B)


      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 }