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
|
package special
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/netip"
"slices"
"strings"
"github.com/Loyalsoldier/geoip/lib"
)
const (
TypeLookup = "lookup"
DescLookup = "Lookup specified IP or CIDR from various formats of data"
)
func init() {
lib.RegisterOutputConfigCreator(TypeLookup, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) {
return NewLookupFromBytes(action, data)
})
lib.RegisterOutputConverter(TypeLookup, &lookup{
Description: DescLookup,
})
}
type lookup struct {
Type string
Action lib.Action
Description string
Search string
SearchList []string
}
func NewLookup(action lib.Action, opts ...lib.OutputOption) lib.OutputConverter {
l := &lookup{
Type: TypeLookup,
Action: action,
Description: DescLookup,
}
for _, opt := range opts {
if opt != nil {
opt(l)
}
}
return l
}
func WithLookupSearch(search string) lib.OutputOption {
return func(s lib.OutputConverter) {
search = strings.TrimSpace(search)
if search == "" {
log.Fatalf("❌ [type %s | action %s] please specify an IP or a CIDR as search target", TypeLookup, s.(*lookup).Action)
}
s.(*lookup).Search = search
}
}
func WithLookupSearchList(lists []string) lib.OutputOption {
return func(s lib.OutputConverter) {
s.(*lookup).SearchList = lists
}
}
func NewLookupFromBytes(action lib.Action, data []byte) (lib.OutputConverter, error) {
var tmp struct {
Search string `json:"search"`
SearchList []string `json:"searchList"`
}
if len(data) > 0 {
if err := json.Unmarshal(data, &tmp); err != nil {
return nil, err
}
}
return NewLookup(
action,
WithLookupSearch(tmp.Search),
WithLookupSearchList(tmp.SearchList),
), nil
}
func (l *lookup) GetType() string {
return l.Type
}
func (l *lookup) GetAction() lib.Action {
return l.Action
}
func (l *lookup) GetDescription() string {
return l.Description
}
func (l *lookup) Output(container lib.Container) error {
switch strings.Contains(l.Search, "/") {
case true: // CIDR
if _, err := netip.ParsePrefix(l.Search); err != nil {
return errors.New("invalid IP or CIDR")
}
case false: // IP
if _, err := netip.ParseAddr(l.Search); err != nil {
return errors.New("invalid IP or CIDR")
}
}
lists, found, _ := container.Lookup(l.Search, l.SearchList...)
if found {
slices.Sort(lists)
fmt.Println(strings.ToLower(strings.Join(lists, ",")))
} else {
fmt.Println("false")
}
return nil
}
|