|
| 1 | +package zgrab2 |
| 2 | + |
| 3 | +import "fmt" |
| 4 | + |
| 5 | +// FlagMap is a function that maps a single-bit bitmask (i.e. a number of the |
| 6 | +// form (1 << x)) to a string representing that bit. |
| 7 | +// If the input is not valid / recognized, it should return a non-nil error, |
| 8 | +// which will cause the flag to be added to the "unknowns" list. |
| 9 | +type FlagMap func(uint64) (string, error) |
| 10 | + |
| 11 | +// MapFlagsToSet gets the "set" (map of strings to true) of values corresponding |
| 12 | +// to the bits in flags. For each bit i set in flags, the result will have |
| 13 | +// result[mapping(i << i)] = true. |
| 14 | +// Any bits for which the mapping returns a non-nil error are instead appended |
| 15 | +// to the unknowns list. |
| 16 | +func MapFlagsToSet(flags uint64, mapping FlagMap) (map[string]bool, []uint64) { |
| 17 | + ret := make(map[string]bool) |
| 18 | + unknowns := []uint64{} |
| 19 | + for i := uint8(0); i < 64; i++ { |
| 20 | + if flags == 0 { |
| 21 | + break |
| 22 | + } |
| 23 | + bit := (flags & 1) << i |
| 24 | + if bit > 0 { |
| 25 | + str, err := mapping(bit) |
| 26 | + if err != nil { |
| 27 | + unknowns = append(unknowns, bit) |
| 28 | + } else { |
| 29 | + ret[str] = true |
| 30 | + } |
| 31 | + } |
| 32 | + flags >>= 1 |
| 33 | + } |
| 34 | + return ret, unknowns |
| 35 | +} |
| 36 | + |
| 37 | +// GetFlagMapFromMap returns a FlagMap function that uses mapping to do the |
| 38 | +// mapping. Values not present in the map are treated as unknown, and a non-nil |
| 39 | +// error is returned in those cases. |
| 40 | +func GetFlagMapFromMap(mapping map[uint64]string) FlagMap { |
| 41 | + return func(bit uint64) (string, error) { |
| 42 | + ret, ok := mapping[bit] |
| 43 | + if ok { |
| 44 | + return ret, nil |
| 45 | + } |
| 46 | + return "", fmt.Errorf("Unknown flag 0x%x", bit) |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +// GetFlagMapFromList returns a FlagMap function mapping the ith bit to the |
| 51 | +// ith entry of bits. |
| 52 | +// bits is a list of labels for the corresponding bits; any empty strings (and |
| 53 | +// bits beyond the end of the list) are treated as unknown. |
| 54 | +func GetFlagMapFromList(bits []string) FlagMap { |
| 55 | + mapping := make(map[uint64]string) |
| 56 | + for i, v := range bits { |
| 57 | + if v != "" { |
| 58 | + mapping[uint64(1)<<uint8(i)] = v |
| 59 | + } |
| 60 | + } |
| 61 | + return GetFlagMapFromMap(mapping) |
| 62 | +} |
| 63 | + |
| 64 | +// FlagsToSet converts an integer flags variable to a set of string labels |
| 65 | +// corresponding to each bit, in the format described by the wiki (see |
| 66 | +// https://github.com/zmap/zgrab2/wiki/Scanner-details). |
| 67 | +// The mapping maps the bit mask value (i.e. a number of the form (1 << x)) to |
| 68 | +// the label for that bit. |
| 69 | +// Flags not present in mapping are appended to the unknown list. |
| 70 | +func FlagsToSet(flags uint64, mapping map[uint64]string) (map[string]bool, []uint64) { |
| 71 | + mapper := GetFlagMapFromMap(mapping) |
| 72 | + return MapFlagsToSet(flags, mapper) |
| 73 | +} |
| 74 | + |
| 75 | +// ListFlagsToSet converts an integer flags variable to a set of string labels |
| 76 | +// corresponding to each bit, in the format described by the wiki (see |
| 77 | +// https://github.com/zmap/zgrab2/wiki/Scanner-details). |
| 78 | +// The ith entry of labels gives the label for the ith bit (i.e. flags & (1<<i)). |
| 79 | +// Empty strings in labels are treated as unknown, as are bits beyond the end |
| 80 | +// of the list. Unknown flags are appended to the unknown list. |
| 81 | +func ListFlagsToSet(flags uint64, labels []string) (map[string]bool, []uint64) { |
| 82 | + mapper := GetFlagMapFromList(labels) |
| 83 | + return MapFlagsToSet(flags, mapper) |
| 84 | +} |
| 85 | + |
| 86 | +// WidenMapKeys8 copies a map with uint8 keys into an equivalent map with uint64 |
| 87 | +// keys for use in the FlagsToSet function. |
| 88 | +func WidenMapKeys8(input map[uint8]string) map[uint64]string { |
| 89 | + ret := make(map[uint64]string, len(input)) |
| 90 | + for k, v := range input { |
| 91 | + ret[uint64(k)] = v |
| 92 | + } |
| 93 | + return ret |
| 94 | +} |
| 95 | + |
| 96 | +// WidenMapKeys16 copies a map with uint8 keys into an equivalent map with |
| 97 | +// uint64 keys for use in the FlagsToSet function. |
| 98 | +func WidenMapKeys16(input map[uint16]string) map[uint64]string { |
| 99 | + ret := make(map[uint64]string, len(input)) |
| 100 | + for k, v := range input { |
| 101 | + ret[uint64(k)] = v |
| 102 | + } |
| 103 | + return ret |
| 104 | +} |
| 105 | + |
| 106 | +// WidenMapKeys32 copies a map with uint8 keys into an equivalent map with |
| 107 | +// uint64 keys for use in the FlagsToSet function. |
| 108 | +func WidenMapKeys32(input map[uint32]string) map[uint64]string { |
| 109 | + ret := make(map[uint64]string, len(input)) |
| 110 | + for k, v := range input { |
| 111 | + ret[uint64(k)] = v |
| 112 | + } |
| 113 | + return ret |
| 114 | +} |
| 115 | + |
| 116 | +// WidenMapKeys copies a map with int keys into an equivalent map with uint64 |
| 117 | +// keys for use in the FlagsToSet function. |
| 118 | +func WidenMapKeys(input map[int]string) map[uint64]string { |
| 119 | + ret := make(map[uint64]string, len(input)) |
| 120 | + for k, v := range input { |
| 121 | + ret[uint64(k)] = v |
| 122 | + } |
| 123 | + return ret |
| 124 | +} |
0 commit comments