forked from zmap/zgrab2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
output.go
150 lines (137 loc) · 4.82 KB
/
output.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package zgrab2
import (
"bufio"
"fmt"
)
// FlagMap is a function that maps a single-bit bitmask (i.e. a number of the
// form (1 << x)) to a string representing that bit.
// If the input is not valid / recognized, it should return a non-nil error,
// which will cause the flag to be added to the "unknowns" list.
type FlagMap func(uint64) (string, error)
// MapFlagsToSet gets the "set" (map of strings to true) of values corresponding
// to the bits in flags. For each bit i set in flags, the result will have
// result[mapping(i << i)] = true.
// Any bits for which the mapping returns a non-nil error are instead appended
// to the unknowns list.
func MapFlagsToSet(flags uint64, mapping FlagMap) (map[string]bool, []uint64) {
ret := make(map[string]bool)
unknowns := []uint64{}
for i := uint8(0); i < 64; i++ {
if flags == 0 {
break
}
bit := (flags & 1) << i
if bit > 0 {
str, err := mapping(bit)
if err != nil {
unknowns = append(unknowns, bit)
} else {
ret[str] = true
}
}
flags >>= 1
}
return ret, unknowns
}
// GetFlagMapFromMap returns a FlagMap function that uses mapping to do the
// mapping. Values not present in the map are treated as unknown, and a non-nil
// error is returned in those cases.
func GetFlagMapFromMap(mapping map[uint64]string) FlagMap {
return func(bit uint64) (string, error) {
ret, ok := mapping[bit]
if ok {
return ret, nil
}
return "", fmt.Errorf("Unknown flag 0x%x", bit)
}
}
// GetFlagMapFromList returns a FlagMap function mapping the ith bit to the
// ith entry of bits.
// bits is a list of labels for the corresponding bits; any empty strings (and
// bits beyond the end of the list) are treated as unknown.
func GetFlagMapFromList(bits []string) FlagMap {
mapping := make(map[uint64]string)
for i, v := range bits {
if v != "" {
mapping[uint64(1)<<uint8(i)] = v
}
}
return GetFlagMapFromMap(mapping)
}
// FlagsToSet converts an integer flags variable to a set of string labels
// corresponding to each bit, in the format described by the wiki (see
// https://github.com/zmap/zgrab2/wiki/Scanner-details).
// The mapping maps the bit mask value (i.e. a number of the form (1 << x)) to
// the label for that bit.
// Flags not present in mapping are appended to the unknown list.
func FlagsToSet(flags uint64, mapping map[uint64]string) (map[string]bool, []uint64) {
mapper := GetFlagMapFromMap(mapping)
return MapFlagsToSet(flags, mapper)
}
// ListFlagsToSet converts an integer flags variable to a set of string labels
// corresponding to each bit, in the format described by the wiki (see
// https://github.com/zmap/zgrab2/wiki/Scanner-details).
// The ith entry of labels gives the label for the ith bit (i.e. flags & (1<<i)).
// Empty strings in labels are treated as unknown, as are bits beyond the end
// of the list. Unknown flags are appended to the unknown list.
func ListFlagsToSet(flags uint64, labels []string) (map[string]bool, []uint64) {
mapper := GetFlagMapFromList(labels)
return MapFlagsToSet(flags, mapper)
}
// WidenMapKeys8 copies a map with uint8 keys into an equivalent map with uint64
// keys for use in the FlagsToSet function.
func WidenMapKeys8(input map[uint8]string) map[uint64]string {
ret := make(map[uint64]string, len(input))
for k, v := range input {
ret[uint64(k)] = v
}
return ret
}
// WidenMapKeys16 copies a map with uint8 keys into an equivalent map with
// uint64 keys for use in the FlagsToSet function.
func WidenMapKeys16(input map[uint16]string) map[uint64]string {
ret := make(map[uint64]string, len(input))
for k, v := range input {
ret[uint64(k)] = v
}
return ret
}
// WidenMapKeys32 copies a map with uint8 keys into an equivalent map with
// uint64 keys for use in the FlagsToSet function.
func WidenMapKeys32(input map[uint32]string) map[uint64]string {
ret := make(map[uint64]string, len(input))
for k, v := range input {
ret[uint64(k)] = v
}
return ret
}
// WidenMapKeys copies a map with int keys into an equivalent map with uint64
// keys for use in the FlagsToSet function.
func WidenMapKeys(input map[int]string) map[uint64]string {
ret := make(map[uint64]string, len(input))
for k, v := range input {
ret[uint64(k)] = v
}
return ret
}
// OutputResultsFunc is a function type for result output functions.
//
// A function of this type receives results on the provided channel
// and outputs them somehow. It returns nil if there are no further
// results or error.
type OutputResultsFunc func(results <-chan []byte) error
// OutputResultsFile is an OutputResultsFunc that write results to
// a filename provided on the command line.
func OutputResultsFile(results <-chan []byte) error {
out := bufio.NewWriter(config.outputFile)
defer out.Flush()
for result := range results {
if _, err := out.Write(result); err != nil {
return err
}
if err := out.WriteByte('\n'); err != nil {
return err
}
}
return nil
}